3 commits - demo/demo moksha/api moksha/commands moksha/templates
by Luke Macken
demo/demo/controllers/root.py | 2 +-
moksha/api/widgets/amqp/amqp.py | 19 +++++++++++++++++++
moksha/api/widgets/stomp/stomp.py | 9 +++++++++
moksha/commands/cli.py | 2 +-
moksha/templates/amqp_socket.mak | 17 +++++++++++++++++
moksha/templates/stomp_socket.mak | 7 +++++++
6 files changed, 54 insertions(+), 2 deletions(-)
New commits:
commit 7dd733953c585ae27b2a6cf242b5cd15e9d10c1d
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 28 15:40:25 2010 -0400
Run the moksha-hub in verbose mode
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
index 5915fcf..2988a69 100755
--- a/moksha/commands/cli.py
+++ b/moksha/commands/cli.py
@@ -62,7 +62,7 @@ class MokshaCLI(object):
self._exec(*orbited)
self._exec('paster', 'serve', get_moksha_config_path())
- self._exec('moksha-hub')
+ self._exec('moksha-hub', '-v')
def list(self):
""" List all available apps, widgets, producers and consumers """
commit 956f405337ceb397b1252a96518eeb2c111b156e
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 28 15:39:58 2010 -0400
We renamed our live widget
diff --git a/demo/demo/controllers/root.py b/demo/demo/controllers/root.py
index 35593b1..d31128c 100644
--- a/demo/demo/controllers/root.py
+++ b/demo/demo/controllers/root.py
@@ -15,7 +15,7 @@ class Root(object):
@expose('mako:moksha.templates.widget')
def livewidget(self, *args, **kwargs):
- tmpl_context.widget = moksha.get_widget('helloworld')
+ tmpl_context.widget = moksha.get_widget('live')
tmpl_context.moksha_socket = moksha.get_widget('moksha_socket')
return dict(options={})
commit 30818c4e4a738e6b19cb5476d60e966d210115e2
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 28 15:01:16 2010 -0400
Add moksha.send_message functions to our AMQP & STOMP sockets
diff --git a/moksha/api/widgets/amqp/amqp.py b/moksha/api/widgets/amqp/amqp.py
index 75da86e..785a1a5 100644
--- a/moksha/api/widgets/amqp/amqp.py
+++ b/moksha/api/widgets/amqp/amqp.py
@@ -159,6 +159,25 @@ class AMQPSocket(Widget):
${onconnectedframe}
moksha_amqp_queue.start();
}
+
+ if (typeof moksha == 'undefined') {
+ moksha = {
+ /* Send an AMQP message to a given topic */
+ send_message: function(topic, body) {
+ moksha_amqp_session.Message('transfer', {
+ accept_mode: 1,
+ acquire_mode: 1,
+ destination: 'amq.topic',
+ _body: $.toJSON(body),
+ _header: {
+ delivery_properties: {
+ routing_key: topic
+ }
+ }
+ });
+ },
+ }
+ }
</script>
"""
hidden = True
diff --git a/moksha/api/widgets/stomp/stomp.py b/moksha/api/widgets/stomp/stomp.py
index 87dc4b4..51c7c13 100644
--- a/moksha/api/widgets/stomp/stomp.py
+++ b/moksha/api/widgets/stomp/stomp.py
@@ -148,6 +148,15 @@ class StompWidget(Widget):
}
}
+ if (typeof moksha == 'undefined') {
+ moksha = {
+ /* Send a STOMP message to a given topic */
+ send_message: function(topic, body) {
+ stomp.send($.toJSON(body), topic)
+ }
+ }
+ }
+
% if notify:
$.jGrowl.defaults.position = 'bottom-right';
% endif
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
index 9e8bb6f..667119f 100644
--- a/moksha/templates/amqp_socket.mak
+++ b/moksha/templates/amqp_socket.mak
@@ -1,3 +1,20 @@
+moksha = {
+ /* Send an AMQP message to a given topic */
+ send_message: function(topic, body) {
+ moksha_amqp_session.Message('transfer', {
+ accept_mode: 1,
+ acquire_mode: 1,
+ destination: 'amq.topic',
+ _body: $.toJSON(body),
+ _header: {
+ delivery_properties: {
+ routing_key: topic
+ }
+ }
+ });
+ },
+}
+
if (typeof moksha_amqp_conn == 'undefined') {
moksha_callbacks = new Object();
moksha_amqp_remote_queue = null;
diff --git a/moksha/templates/stomp_socket.mak b/moksha/templates/stomp_socket.mak
index e4eb0cd..bcf252a 100644
--- a/moksha/templates/stomp_socket.mak
+++ b/moksha/templates/stomp_socket.mak
@@ -1,3 +1,10 @@
+moksha = {
+ /* Send a STOMP message to a given topic */
+ send_message: function(topic, body) {
+ stomp.send($.toJSON(body), topic)
+ },
+}
+
if (typeof TCPSocket == 'undefined') {
moksha_callbacks = new Object();
moksha_socket_busy = false;
13 years, 6 months
.gitignore
by Luke Macken
.gitignore | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 87a090c8222c8905f159cca72d24e20b356edd8c
Author: Ralph Bean <ralph.bean(a)gmail.com>
Date: Sun Oct 24 23:50:06 2010 -0400
adding build to gitignore
diff --git a/.gitignore b/.gitignore
index 432dd88..1a765d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ moksha/apps/*/*egg-info
tg2-bootstrap.py
*.cachegrind
dist
+build
13 years, 6 months
moksha/commands
by Luke Macken
moksha/commands/cli.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 7afa3807f94395b8ee28d59e1b8d844589b1ef10
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 21 22:28:30 2010 -0400
Fix a broken string expansion
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
index 1f72713..5915fcf 100755
--- a/moksha/commands/cli.py
+++ b/moksha/commands/cli.py
@@ -45,7 +45,7 @@ class MokshaCLI(object):
def _exec(self, process, *args, **kw):
args = args and [process] + list(args) or [process]
- print "Running %s %s" % ' '.join(args)
+ print "Running %s" % ' '.join(args)
pp = MokshaProcessProtocol(name=process)
process = reactor.spawnProcess(pp, process, args,
env={'PYTHONPATH': os.getcwd()}, **kw)
13 years, 7 months
2 commits - moksha/commands moksha/controllers moksha/templates
by Luke Macken
moksha/commands/cli.py | 2 -
moksha/controllers/root.py | 36 +++++++++++++++++-
moksha/templates/amqp_socket.mak | 76 ++++++++++++++++++++++++++++++++++++++
moksha/templates/stomp_socket.mak | 73 ++++++++++++++++++++++++++++++++++++
4 files changed, 185 insertions(+), 2 deletions(-)
New commits:
commit 077f29f1ffffcf96e6e57bf0e9ca1031a99d090a
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 21 12:45:58 2010 -0400
Initial implementation of stand-alone moksha live sockets.
This can be used for injecting live sockets into static html pages.
diff --git a/moksha/controllers/root.py b/moksha/controllers/root.py
index 51ec227..2f2e397 100644
--- a/moksha/controllers/root.py
+++ b/moksha/controllers/root.py
@@ -19,8 +19,9 @@
import moksha
import pylons
-from tg import url
+from tg import url, config
from tg import expose, flash, tmpl_context, redirect
+from tg.decorators import override_template
from pylons.i18n import ugettext as _
from moksha.lib.base import BaseController
@@ -57,6 +58,39 @@ class RootController(BaseController):
# moksha.root entry-point, then redirect to a moksha logo
return DefaultRootController(), remainder
+ @expose()
+ def livesocket(self, topic=None, callback=None):
+ """Returns a raw Moksha live socket, for use in non-Moksha apps.
+
+ <script> function bar(msg) { alert('bar(' + msg + ')'); } </script>
+ <script type="text/javascript" src="http://localhost:8080/livesocket?topic=foo&callback=bar"> </script>
+
+ """
+ data = {'topic': topic, 'callback': callback}
+ backend = config.get('moksha.livesocket.backend', 'stomp').lower()
+ if backend == 'stomp':
+ override_template(self.livesocket, 'mako:moksha.templates.stomp_socket')
+ data['stomp_host'] = config.get('stomp_host', 'localhost')
+ data['stomp_port'] = config.get('stomp_port', 61613)
+ data['stomp_user'] = config.get('stomp_user', 'guest')
+ data['stomp_pass'] = config.get('stomp_pass', 'guest')
+ elif backend == 'amqp':
+ override_template(self.livesocket, 'mako:moksha.templates.amqp_socket')
+ data['amqp_broker_host'] = config.get('amqp_broker_host', 'localhost')
+ 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)
+ data['orbited_scheme'] = config.get('orbited_scheme', 'http')
+ data['orbited_url'] = '%s://%s:%s' % (data['orbited_scheme'],
+ data['orbited_host'], data['orbited_port'])
+
+ return data
+
@expose('mako:moksha.templates.login')
def login(self, came_from=None):
"""Start the user login."""
diff --git a/moksha/templates/amqp_socket.mak b/moksha/templates/amqp_socket.mak
new file mode 100644
index 0000000..9e8bb6f
--- /dev/null
+++ b/moksha/templates/amqp_socket.mak
@@ -0,0 +1,76 @@
+if (typeof moksha_amqp_conn == 'undefined') {
+ moksha_callbacks = new Object();
+ moksha_amqp_remote_queue = null;
+ moksha_amqp_queue = null;
+ moksha_amqp_on_message = function(msg) {
+ var dest = msg.header.delivery_properties.routing_key;
+ if (moksha_callbacks[dest]) {
+ for (var i=0; i < moksha_callbacks[dest].length; i++) {
+ moksha_callbacks[dest][i](msg.body);
+ }
+ }
+ }
+}
+
+## Register our topic callbacks
+var topic = "${topic}";
+if (!moksha_callbacks[topic]) {
+ moksha_callbacks[topic] = [];
+}
+moksha_callbacks[topic].push(function(frame) {
+ ${callback}(frame);
+});
+
+## Create a new AMQP client
+if (typeof moksha_amqp_conn == 'undefined') {
+ document.domain = document.domain;
+ $.getScript("${orbited_url}/static/Orbited.js", function() {
+ 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() {
+ moksha_amqp_conn = new amqp.Connection({
+ host: '${amqp_broker_host}',
+ port: ${amqp_broker_port},
+ username: '${amqp_broker_user}',
+ password: '${amqp_broker_pass}',
+ });
+ moksha_amqp_conn.start();
+
+ moksha_amqp_session = moksha_amqp_conn.create_session(
+ 'moksha_socket_' + (new Date().getTime() + Math.random()));
+
+ moksha_amqp_remote_queue = 'moksha_socket_queue_' +
+ moksha_amqp_session.name;
+
+ moksha_amqp_session.Queue('declare', {
+ queue: moksha_amqp_remote_queue
+ });
+ moksha_amqp_queue = moksha_amqp_session.create_local_queue({
+ name: 'local_queue'
+ });
+
+ moksha_amqp_queue.subscribe({
+ exchange: 'amq.topic',
+ remote_queue: moksha_amqp_remote_queue,
+ binding_key: '${topic}',
+ callback: moksha_amqp_on_message,
+ });
+
+ moksha_amqp_queue.start();
+ });
+ });
+ });
+ });
+} else {
+ ## Utilize the existing Moksha AMQP socket connection
+ moksha_amqp_queue.subscribe({
+ exchange: 'amq.topic',
+ remote_queue: moksha_amqp_remote_queue,
+ binding_key: '${topic}',
+ callback: moksha_amqp_on_message,
+ });
+ moksha_amqp_queue.start();
+}
diff --git a/moksha/templates/stomp_socket.mak b/moksha/templates/stomp_socket.mak
new file mode 100644
index 0000000..e4eb0cd
--- /dev/null
+++ b/moksha/templates/stomp_socket.mak
@@ -0,0 +1,73 @@
+if (typeof TCPSocket == 'undefined') {
+ moksha_callbacks = new Object();
+ moksha_socket_busy = false;
+}
+
+## Register our topic callbacks
+var topic = "${topic}";
+if (!moksha_callbacks[topic]) {
+ moksha_callbacks[topic] = [];
+}
+moksha_callbacks[topic].push(function(frame) {
+ ${callback}(frame);
+});
+
+if (typeof TCPSocket == 'undefined') {
+ document.domain = document.domain;
+ moksha_socket_busy = true;
+ $.getScript("${orbited_url}/static/Orbited.js", function(){
+ Orbited.settings.port = ${orbited_port};
+ Orbited.settings.hostname = '${orbited_host}';
+ Orbited.settings.streaming = true;
+ TCPSocket = Orbited.TCPSocket;
+ $.getScript("${orbited_url}/static/protocols/stomp/stomp.js", function(){
+ ## Create a new TCPSocket & Stomp client
+ stomp = new STOMPClient();
+ stomp.onopen = function(){};
+ stomp.onclose = function(c){};
+ stomp.onerror = function(error){};
+ stomp.onerrorframe = function(f){};
+ stomp.onconnectedframe = function(){
+ moksha_socket_busy = false;
+ $('body').triggerHandler('moksha.socket_ready');
+ stomp.subscribe('${topic}')
+ };
+ stomp.onmessageframe = function(f){
+ var dest = f.headers.destination;
+/*
+ var json = null;
+ try {
+ var json = $.parseJSON(f.body);
+ } catch(err) {
+ console.log("Unable to decode JSON message body:");
+ console.log(f.body);
+ }
+*/
+ if (moksha_callbacks[dest]) {
+ for (var i=0; i < moksha_callbacks[dest].length; i++) {
+ moksha_callbacks[dest][i](f.body);
+ }
+ }
+ };
+
+ stomp.connect('${stomp_host}', ${stomp_port},
+ '${stomp_user}', '${stomp_pass}');
+ });
+ });
+
+} else {
+ ## Utilize the existing stomp connection
+ if (moksha_socket_busy) {
+ $('body').bind('moksha.socket_ready', function() {
+ stomp.subscribe('${topic}')
+ });
+ } else {
+ stomp.subscribe('${topic}')
+ }
+}
+
+window.onbeforeunload = function() {
+ if (typeof stomp != 'undefined') {
+ stomp.reset();
+ }
+}
commit 13b40da646d1b0af801dde8716d295934c881aca
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 21 12:45:31 2010 -0400
Minor CLI output tweak
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
index f44ce2d..1f72713 100755
--- a/moksha/commands/cli.py
+++ b/moksha/commands/cli.py
@@ -45,7 +45,7 @@ class MokshaCLI(object):
def _exec(self, process, *args, **kw):
args = args and [process] + list(args) or [process]
- print "Running %s %s" % (process, ' '.join(args))
+ print "Running %s %s" % ' '.join(args)
pp = MokshaProcessProtocol(name=process)
process = reactor.spawnProcess(pp, process, args,
env={'PYTHONPATH': os.getcwd()}, **kw)
13 years, 7 months
docs/main
by Luke Macken
docs/main/HelloWorld.rst | 85 +++++++++++++++++++++++++++++++++++++++++------
1 file changed, 75 insertions(+), 10 deletions(-)
New commits:
commit 38b694911821846acb819f3d63164e276b1c4d5b
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Oct 21 12:44:19 2010 -0400
More Hello World document improvements
diff --git a/docs/main/HelloWorld.rst b/docs/main/HelloWorld.rst
index 3c6e8e4..729c75a 100644
--- a/docs/main/HelloWorld.rst
+++ b/docs/main/HelloWorld.rst
@@ -2,8 +2,6 @@
Hello World Moksha Demo
=======================
-Ok, lets get down to the basics.
-
The goal of this tutorial is to show the simplicity of Moksha's API by creating
basic "Hello World" components in one demo.
@@ -14,7 +12,7 @@ The Controller
This is the most basic of controllers.
-demo/controllers/root.py
+`demo/controllers/root.py`
.. code-block:: python
@@ -27,14 +25,20 @@ demo/controllers/root.py
return 'Hello World!'
-Ok, so here we have a trivial TurboGears controller. How do we plug this into Moksha and actually run it?
+Ok, so here we have a trivial TurboGears controller. How do we plug this into
+Moksha and actually run it?
-Let's say we want this index method to be the root of our application. To accomplish this we add it to the `[moksha.root]` entry-point in our setup.py::
+Let's say we want this index method to be the root of our application. To
+accomplish this we add it to the `[moksha.root]` entry-point in our setup.py::
[moksha.root]
root = demo.controllers.root:Root
+.. seealso::
+
+ :doc:`PluginEntryPoints`
+
Running the Moksha stack
------------------------
@@ -47,6 +51,11 @@ Running the Moksha stack
$ curl http://localhost:8080/
Hello World
+
+.. seealso::
+
+ :doc:`MokshaCLI`
+
Bringing a templating engine into the mix
-----------------------------------------
@@ -80,6 +89,8 @@ Now let's plug in our Mako template into our Root controller.
Building a basic Widget
-----------------------
+.. image:: ../_static/widget.png
+
.. code-block:: python
from tw.api import Widget
@@ -126,8 +137,9 @@ Building a basic Widget
.. seealso::
- `ToscaWidgets documentation <http://toscawidgets.org/documentation/ToscaWidgets>`_
- `ToscaWidgets2 documentation <http://toscawidgets.org/documentation/tw2.core>`_
+ :doc:`Widgets`
+
+
Creating a message producer
---------------------------
@@ -143,6 +155,13 @@ Creating a message producer
def poll(self):
self.send_message('helloworld', {'msg': 'Hello World!'})
+.. seealso::
+
+ :doc:`Messaging`
+
+.. seealso::
+
+ :doc:`Producers`
Creating a message consumer
---------------------------
@@ -160,10 +179,20 @@ Creating a message consumer
def consume(self, message):
self.log.info('Received message: ' + message['body']['msg'])
+.. seealso::
+
+ :doc:`Consumers`
Running the Moksha Hub
----------------------
-<watch output scrolling>
+
+.. image:: ../_static/moksha-hub.png
+
+<consumer output>
+
+.. seealso::
+
+ :doc:`MokshaHub`
Creating a Live Widget!
-----------------------
@@ -175,7 +204,7 @@ bundle of HTML/JavaScript/CSS/Server-side logic Making it "live" entails
having the widget "subscribe" to "topics" and perform some action upon
new messages as they arrive in the users web browser.
-<live widget diagram?>
+.. image:: ../_static/live_widgets.png
`demo/widget.py`
@@ -206,6 +235,10 @@ new messages as they arrive in the users web browser.
return dict(options={})
+.. seealso::
+
+ :doc:`LiveWidget`
+
Creating a database model
-------------------------
@@ -224,10 +257,31 @@ Creating a database model
message = Column(Text)
timestamp = Column(DateTime, default=datetime.now)
+.. seealso::
+
+ `Working with SQLAlchemy and your data model <http://turbogears.org/2.1/docs/main/SQLAlchemy.html>`_
Populating our database
~~~~~~~~~~~~~~~~~~~~~~~
-via the consumer upon message arrival
+<via the consumer upon message arrival>
+
+.. code-block:: python
+
+ from moksha.api.hub.consumer import Consumer
+ from demo.model import HelloWorldModel
+
+ class HelloWorldConsumer(Consumer):
+ topic = 'helloworld'
+ app = 'helloworld'
+
+ def consume(self, message):
+ self.log.info('Received message: ' + message['body']['msg'])
+
+ entry = HelloWorldModel()
+ entry.message = message['body']['msg']
+ self.DBSession.add(entry)
+ self.DBSession.commit()
+
Querying our database
~~~~~~~~~~~~~~~~~~~~~
@@ -243,6 +297,9 @@ Querying our database
entries = DBSession.query(HelloWorldModel).all()
return dict(entries=entries)
+.. seealso::
+
+ `SQLAlchemy documentation <http://www.sqlalchemy.org/docs>`_
Caching
-------
@@ -263,3 +320,11 @@ Caching
def _get_entries(self, *args, **kwargs):
return DBSession.query(HelloWorldModel).all()
+
+.. seealso::
+
+ `Caching in TurboGears2 <http://turbogears.org/2.1/docs/main/Caching.html>`_
+
+.. seealso::
+
+ `Beaker documentation <http://beaker.groovie.org>`_
13 years, 7 months
2 commits - demo/demo demo/setup.py docs/main moksha/api
by Luke Macken
demo/demo/controllers/root.py | 7 ++---
demo/demo/producer.py | 2 -
demo/demo/widget.py | 11 --------
demo/demo/widgets/basic.py | 11 ++++++++
demo/demo/widgets/live.py | 11 ++++++++
demo/setup.py | 3 +-
docs/main/HelloWorld.rst | 53 ++++++++++++++++++++++++++++++++++++++--
moksha/api/widgets/amqp/amqp.py | 3 +-
8 files changed, 81 insertions(+), 20 deletions(-)
New commits:
commit 4a478e34a34c29f826cd9bd97fe7d58da84f08d7
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 19 13:31:03 2010 -0400
More demo improvements
diff --git a/demo/demo/controllers/root.py b/demo/demo/controllers/root.py
index 1f77d96..35593b1 100644
--- a/demo/demo/controllers/root.py
+++ b/demo/demo/controllers/root.py
@@ -29,11 +29,10 @@ class Root(object):
def cached_model(self, *args, **kwargs):
from pylons import cache
mycache = cache.get_cache('helloworld')
- entries = mycache.get_value(key='entries', createfunc=self._expensive_call,
+ entries = mycache.get_value(key='entries', createfunc=self._get_entries,
expiretime=3600)
return dict(entries=entries)
- def _expensive_call(self, *args, **kwargs):
+ def _get_entries(self, *args, **kwargs):
from demo.model import DBSession, HelloWorldModel
- entries = DBSession.query(HelloWorldModel).all()
- return entries
+ return DBSession.query(HelloWorldModel).all()
diff --git a/demo/demo/producer.py b/demo/demo/producer.py
index bfd44f4..7ad039d 100644
--- a/demo/demo/producer.py
+++ b/demo/demo/producer.py
@@ -1,5 +1,5 @@
-from moksha.api.hub.producer import PollingProducer
from datetime import timedelta
+from moksha.api.hub.producer import PollingProducer
class HelloWorldProducer(PollingProducer):
frequency = timedelta(seconds=3)
diff --git a/demo/demo/widget.py b/demo/demo/widget.py
deleted file mode 100644
index f9d0ad4..0000000
--- a/demo/demo/widget.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from moksha.api.widgets.live import LiveWidget
-
-class HelloWorldWidget(LiveWidget):
- topic = "helloworld"
- template = """
- <b>Hello World Widget</b>
- <ul id="data"/>
- """
- onmessage = """
- $('<li/>').text(json.msg).prependTo('#data');
- """
diff --git a/demo/demo/widgets/__init__.py b/demo/demo/widgets/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/demo/demo/widgets/basic.py b/demo/demo/widgets/basic.py
new file mode 100644
index 0000000..7b7e48a
--- /dev/null
+++ b/demo/demo/widgets/basic.py
@@ -0,0 +1,11 @@
+from tw.api import Widget
+
+class HelloWorldWidget(Widget):
+ params = ['msg']
+ msg = 'Hello World'
+ template = '${msg}'
+ engine_name = 'mako'
+
+ def update_params(self, d):
+ """ Render-time logic """
+ super(HelloWorldWidget, self).update_params(d)
diff --git a/demo/demo/widgets/live.py b/demo/demo/widgets/live.py
new file mode 100644
index 0000000..f9d0ad4
--- /dev/null
+++ b/demo/demo/widgets/live.py
@@ -0,0 +1,11 @@
+from moksha.api.widgets.live import LiveWidget
+
+class HelloWorldWidget(LiveWidget):
+ topic = "helloworld"
+ template = """
+ <b>Hello World Widget</b>
+ <ul id="data"/>
+ """
+ onmessage = """
+ $('<li/>').text(json.msg).prependTo('#data');
+ """
diff --git a/demo/setup.py b/demo/setup.py
index 10868ef..03e57d8 100644
--- a/demo/setup.py
+++ b/demo/setup.py
@@ -28,7 +28,8 @@ setup(
helloworld = demo.consumer:HelloWorldConsumer
[moksha.widget]
- helloworld = demo.widget:HelloWorldWidget
+ basic = demo.widgets.basic:HelloWorldWidget
+ live = demo.widgets.live:HelloWorldWidget
"""
)
diff --git a/docs/main/HelloWorld.rst b/docs/main/HelloWorld.rst
index ae46ee3..3c6e8e4 100644
--- a/docs/main/HelloWorld.rst
+++ b/docs/main/HelloWorld.rst
@@ -50,7 +50,6 @@ Running the Moksha stack
Bringing a templating engine into the mix
-----------------------------------------
-
The previous example just returned a string from our controller. What if we
want to use one of the many powerful templating engines out there?
@@ -78,7 +77,57 @@ Now let's plug in our Mako template into our Root controller.
return {'msg': 'Hello World!'}
-** Messaging **
+Building a basic Widget
+-----------------------
+
+.. code-block:: python
+
+ from tw.api import Widget
+
+ class HelloWorldWidget(Widget):
+ params = ['msg']
+ msg = 'Hello World'
+ template = '${msg}'
+ engine_name = 'mako'
+
+ def update_params(self, d):
+ """ Render-time logic """
+ super(HelloWorldWidget, self).update_params(d)
+
+
+`setup.py`
+
+.. code-block:: python
+
+ [moksha.widget]
+ helloworld = demo.widgets:HelloWorldWidget
+
+.. code-block:: bash
+
+ $ curl http://localhost:8080/widgets/basic
+
+.. code-block:: html
+
+ <html>
+ <head></head>
+ <body>Hello World</body>
+ </html>
+
+.. code-block:: bash
+
+ $ curl http://localhost:8080/widgets/basic?msg=foobar
+
+.. code-block:: html
+
+ <html>
+ <head></head>
+ <body>foobar</body>
+ </html>
+
+.. seealso::
+
+ `ToscaWidgets documentation <http://toscawidgets.org/documentation/ToscaWidgets>`_
+ `ToscaWidgets2 documentation <http://toscawidgets.org/documentation/tw2.core>`_
Creating a message producer
---------------------------
commit 2690232e93fea5a926cc6782ed33370d67f5af89
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 15 02:11:04 2010 -0400
Have our AMQPSocket require moksha_js
diff --git a/moksha/api/widgets/amqp/amqp.py b/moksha/api/widgets/amqp/amqp.py
index 2dd6664..75da86e 100644
--- a/moksha/api/widgets/amqp/amqp.py
+++ b/moksha/api/widgets/amqp/amqp.py
@@ -29,6 +29,7 @@ from paste.deploy.converters import asbool
from moksha.api.widgets.orbited import orbited_host, orbited_port, orbited_url
from moksha.api.widgets.orbited import orbited_js
from moksha.lib.helpers import defaultdict, listify
+from moksha.widgets.moksha_js import moksha_js
from moksha.widgets.notify import moksha_notify
from moksha.widgets.json import jquery_json_js
@@ -66,7 +67,7 @@ def amqp_unsubscribe(topic):
class AMQPSocket(Widget):
callbacks = ['onconnectedframe', 'onmessageframe']
- javascript = [jquery_json_js, kamaloka_qpid_js]
+ javascript = [jquery_json_js, moksha_js, kamaloka_qpid_js]
params = callbacks[:] + ['topics', 'notify', 'orbited_host',
'orbited_port', 'orbited_url', 'orbited_js', 'amqp_broker_host',
'amqp_broker_port', 'amqp_broker_user', 'amqp_broker_pass',
13 years, 7 months
3 commits - docs/main
by Luke Macken
docs/main/HelloWorld.rst | 90 +++++++++++++++++++++++++++++++++++++--
docs/main/MessagingScenarios.rst | 2
2 files changed, 87 insertions(+), 5 deletions(-)
New commits:
commit ca90cf5afbf74afe3da60301899c83c170a789f9
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 23:17:29 2010 -0400
Fix a typo in the docs
diff --git a/docs/main/MessagingScenarios.rst b/docs/main/MessagingScenarios.rst
index f33900e..73b02f0 100644
--- a/docs/main/MessagingScenarios.rst
+++ b/docs/main/MessagingScenarios.rst
@@ -14,7 +14,7 @@ Cons:
Pros
- - STOMP/AMQP broker briding
+ - STOMP/AMQP broker bridging
Cons
- Not very well tested
- May or may not work as expected
commit e97174d119868579f57ebe064059d03b391c6f73
Merge: 9a89cdd... 24722fe...
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 21:51:06 2010 -0400
Merge branch 'master' of git+ssh://git.fedorahosted.org/git/moksha
commit 9a89cdd9312960eca8e717db4b2f34f387162b86
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 21:50:01 2010 -0400
More updates to our Hello World doc
diff --git a/docs/main/HelloWorld.rst b/docs/main/HelloWorld.rst
index ef0759f..6e8229a 100644
--- a/docs/main/HelloWorld.rst
+++ b/docs/main/HelloWorld.rst
@@ -23,7 +23,7 @@ demo/controllers/root.py
class Root(object):
@expose()
- def index(self, *args, **kwargs):
+ def index(self):
return 'Hello World!'
@@ -61,19 +61,49 @@ Now let's plug in our Mako template into our Root controller.
.. code-block:: python
@expose('mako:demo.templates.template')
- def index(self, *args, **kwargs):
+ def index(self):
""" An example controller method exposed with a Mako template """
return {'msg': 'Hello World!'}
-** Messaging
+** Messaging **
Creating a message producer
---------------------------
+.. code-block:: python
+
+ from datetime import timedelta
+ from moksha.api.hub.producer import PollingProducer
+
+ class HelloWorldProducer(PollingProducer):
+ frequency = timedelta(seconds=3)
+
+ def poll(self):
+ self.send_message('helloworld', {'msg': 'Hello World!'})
+
+
Creating a message consumer
---------------------------
+`demo/consumer.py`
+
+.. code-block:: python
+
+ from moksha.api.hub.consumer import Consumer
+ from demo.model import HelloWorldModel
+
+ class HelloWorldConsumer(Consumer):
+ topic = 'helloworld'
+
+ def consume(self, message):
+ self.log.info('Received message: ' + message['body']['msg'])
+
+
+Running the Moksha Hub
+----------------------
+<watch output scrolling>
+
Creating a Live Widget!
-----------------------
@@ -109,7 +139,7 @@ new messages as they arrive in the users web browser.
.. code-block:: python
@expose('mako:moksha.templates.widget')
- def livewidget(self, *args, **kwargs):
+ def livewidget(self):
tmpl_context.widget = moksha.get_widget('helloworld')
tmpl_context.moksha_socket = moksha.get_widget('moksha_socket')
return dict(options={})
@@ -118,5 +148,57 @@ new messages as they arrive in the users web browser.
Creating a database model
-------------------------
+`demo.model.model.py`
+
+.. code-block:: python
+
+ from datetime import datetime
+ from sqlalchemy import Integer, Text, DateTime, Column
+ from demo.model import DeclarativeBase
+
+ class HelloWorldModel(DeclarativeBase):
+ __tablename__ = 'helloworld'
+
+ id = Column(Integer, autoincrement=True, primary_key=True)
+ message = Column(Text)
+ timestamp = Column(DateTime, default=datetime.now)
+
+
+Populating our database
+~~~~~~~~~~~~~~~~~~~~~~~
+via the consumer upon message arrival
+
+Querying our database
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ from demo.model import DBSession, HelloWorldModel
+
+ class Root(object):
+
+ @expose('mako:demo.templates.model')
+ def model(self, *args, **kwargs):
+ entries = DBSession.query(HelloWorldModel).all()
+ return dict(entries=entries)
+
+
Caching
-------
+
+.. code-block:: python
+
+ from pylons import cache
+ from demo.model import DBSession, HelloWorldModel
+
+ class Root(object):
+
+ @expose('mako:demo.templates.model')
+ def model(self):
+ mycache = cache.get_cache('helloworld')
+ entries = mycache.get_value(key='entries', createfunc=self._get_entries,
+ expiretime=3600)
+ return dict(entries=entries)
+
+ def _get_entries(self, *args, **kwargs):
+ return DBSession.query(HelloWorldModel).all()
13 years, 7 months
3 commits - docs/main moksha/commands moksha.spec moksha/widgets pavement.py
by Luke Macken
docs/main/HelloWorld.rst | 12 ++++++++++++
moksha.spec | 23 ++++++-----------------
pavement.py | 4 ++--
3 files changed, 20 insertions(+), 19 deletions(-)
New commits:
commit 24722fe8834d36e7276c52b0017d6a5990fd4727
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 21:46:07 2010 -0400
Some permission tweaks, and don't install the non-existant hub subpackage
diff --git a/moksha/widgets/notify/static/jquery.jgrowl.css b/moksha/widgets/notify/static/jquery.jgrowl.css
old mode 100755
new mode 100644
diff --git a/moksha/widgets/notify/static/jquery.jgrowl.js b/moksha/widgets/notify/static/jquery.jgrowl.js
old mode 100755
new mode 100644
diff --git a/pavement.py b/pavement.py
index 8f51454..cfad43e 100644
--- a/pavement.py
+++ b/pavement.py
@@ -190,8 +190,8 @@ def reinstall():
sh('mv dist/* ~/rpmbuild/SOURCES/')
sh('cp moksha.spec ~/rpmbuild/SPECS/')
sh('rpmbuild -ba ~/rpmbuild/SPECS/moksha.spec')
- sh('sudo rpm -e --nodeps moksha{,-docs,-server,-hub}', ignore_error=True)
- sh('sudo rpm -ivh ~/rpmbuild/RPMS/noarch/moksha{,-docs,-server,-hub}-%s-1.*noarch.rpm' % options.version.number)
+ sh('sudo rpm -e --nodeps moksha{,-docs,-server}', ignore_error=True)
+ sh('sudo rpm -ivh ~/rpmbuild/RPMS/noarch/moksha{,-docs,-server}-%s-1.*noarch.rpm' % options.version.number)
@task
def restart_httpd():
commit 3be6fa36cb119f07bd66a75cf8794acd8b021551
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 21:44:55 2010 -0400
RPM updates.
- Remove the hub subpackage until we really need it
- Don't drop the production.ini into place automatically. Start with the dev
ini first.
- Require twisted and python-stomper
-
diff --git a/moksha.spec b/moksha.spec
index 7b1f8d2..e7f9acd 100644
--- a/moksha.spec
+++ b/moksha.spec
@@ -50,6 +50,8 @@ Requires: pytz
Requires: pyevent
Requires: python-repoze-who-testutil
Requires: python-BeautifulSoup
+Requires: python-twisted
+Requires: python-stomper
%description
Moksha is a platform for creating real-time collaborative web applications. It
@@ -77,16 +79,6 @@ Requires: mod_wsgi httpd
%description server
This package contains an Apache mod_wsgi configuration for Moksha.
-%package hub
-Summary: Moksha Hub
-Group: Applications/Internet
-Requires: %{name} = %{version}-%{release}
-Requires: python-twisted
-Requires: python-stomper
-
-%description hub
-This package contains the Moksha Hub.
-
%prep
%setup -q
@@ -117,9 +109,9 @@ make -C docs html
%{__install} production/apache/moksha.conf %{buildroot}%{_sysconfdir}/httpd/conf.d/
%{__install} production/nginx/* %{buildroot}%{_datadir}/%{name}/production/nginx
%{__install} production/rabbitmq/* %{buildroot}%{_datadir}/%{name}/production/rabbitmq
-%{__cp} production/sample-production.ini %{buildroot}%{_sysconfdir}/%{name}/production.ini
+%{__cp} production/sample-production.ini %{buildroot}%{_sysconfdir}/%{name}/sample-production.ini
%{__cp} development.ini %{buildroot}%{_sysconfdir}/%{name}/development.ini
-%{__sed} -i -e 's/$VERSION/%{version}/g' %{buildroot}%{_sysconfdir}/%{name}/production.ini
+%{__sed} -i -e 's/$VERSION/%{version}/g' %{buildroot}%{_sysconfdir}/%{name}/sample-production.ini
%{__cp} orbited.cfg %{buildroot}%{_sysconfdir}/%{name}/orbited.cfg
%{__install} production/moksha-hub %{buildroot}%{_bindir}/moksha-hub
@@ -147,6 +139,8 @@ restorecon -Rv /var/cache/moksha
%defattr(-,root,root,-)
%doc README AUTHORS LICENSE COPYING
%{_bindir}/moksha
+%{_bindir}/moksha-hub
+%{_sysconfdir}/init.d/moksha-hub
%{python_sitelib}/%{name}/
%{python_sitelib}/%{name}-%{version}-py%{pyver}.egg-info/
%attr(-,apache,apache) %dir %{_localstatedir}/lib/%{name}
@@ -158,11 +152,6 @@ restorecon -Rv /var/cache/moksha
%config(noreplace) %{_sysconfdir}/%{name}/orbited.cfg
%attr(-,apache,apache) %dir %{_localstatedir}/cache/%{name}/
-%files hub
-%defattr(-,root,root,-)
-%{_bindir}/moksha-hub
-%{_sysconfdir}/init.d/moksha-hub
-
%files docs
%defattr(-,root,root)
%doc docs/_build/html
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
old mode 100644
new mode 100755
commit c82744874c18d7bfa5297f94a62b6fcd6f4c99c3
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Oct 12 21:44:25 2010 -0400
Make a note of running the moksha stack in our hello world doc
diff --git a/docs/main/HelloWorld.rst b/docs/main/HelloWorld.rst
index ef0759f..0312d3c 100644
--- a/docs/main/HelloWorld.rst
+++ b/docs/main/HelloWorld.rst
@@ -35,6 +35,18 @@ Let's say we want this index method to be the root of our application. To accom
root = demo.controllers.root:Root
+Running the Moksha stack
+------------------------
+
+.. code-block:: bash
+
+ $ moksha start
+
+.. code-block:: bash
+
+ $ curl http://localhost:8080/
+ Hello World
+
Bringing a templating engine into the mix
-----------------------------------------
13 years, 7 months
docs/contents.rst docs/main
by Luke Macken
docs/contents.rst | 1
docs/main/HelloWorld.rst | 122 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 123 insertions(+)
New commits:
commit 9afb005062f65f3cf25a61616e9f92c051dfba12
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 8 16:07:30 2010 -0400
Add the beginnings of a Hello World demo / tutorial
diff --git a/docs/contents.rst b/docs/contents.rst
index 478cf86..2119121 100644
--- a/docs/contents.rst
+++ b/docs/contents.rst
@@ -7,6 +7,7 @@
main/Vision
main/Architecture
main/GettingStarted
+ main/HelloWorld
main/Widgets
main/PluginEntryPoints
main/Messaging
diff --git a/docs/main/HelloWorld.rst b/docs/main/HelloWorld.rst
new file mode 100644
index 0000000..ef0759f
--- /dev/null
+++ b/docs/main/HelloWorld.rst
@@ -0,0 +1,122 @@
+=======================
+Hello World Moksha Demo
+=======================
+
+Ok, lets get down to the basics.
+
+The goal of this tutorial is to show the simplicity of Moksha's API by creating
+basic "Hello World" components in one demo.
+
+<link to directory of code and tarball>
+
+The Controller
+--------------
+
+This is the most basic of controllers.
+
+demo/controllers/root.py
+
+.. code-block:: python
+
+ from tg import expose
+
+ class Root(object):
+
+ @expose()
+ def index(self, *args, **kwargs):
+ return 'Hello World!'
+
+
+Ok, so here we have a trivial TurboGears controller. How do we plug this into Moksha and actually run it?
+
+Let's say we want this index method to be the root of our application. To accomplish this we add it to the `[moksha.root]` entry-point in our setup.py::
+
+ [moksha.root]
+ root = demo.controllers.root:Root
+
+
+Bringing a templating engine into the mix
+-----------------------------------------
+
+
+The previous example just returned a string from our controller. What if we
+want to use one of the many powerful templating engines out there?
+
+TurboGears supports a variety of engines, including Genshi, Mako, Jinja, etc.
+
+So, lets create a dead simple Mako template.
+
+`demo/templates/template.mak`
+
+.. code-block:: html
+
+ <html>
+ <head><title>${msg}</title></head>
+ <body>${msg}</body>
+ </html>
+
+
+Now let's plug in our Mako template into our Root controller.
+
+.. code-block:: python
+
+ @expose('mako:demo.templates.template')
+ def index(self, *args, **kwargs):
+ """ An example controller method exposed with a Mako template """
+ return {'msg': 'Hello World!'}
+
+
+** Messaging
+
+Creating a message producer
+---------------------------
+
+Creating a message consumer
+---------------------------
+
+Creating a Live Widget!
+-----------------------
+
+Ok, on to the fun stuff.
+
+Moksha provides an API for creating "live widgets". A widget is a re-usable
+bundle of HTML/JavaScript/CSS/Server-side logic Making it "live" entails
+having the widget "subscribe" to "topics" and perform some action upon
+new messages as they arrive in the users web browser.
+
+<live widget diagram?>
+
+`demo/widget.py`
+
+.. code-block:: python
+
+ from moksha.api.widgets.live import LiveWidget
+
+ class HelloWorldWidget(LiveWidget):
+ topic = "helloworld"
+ template = """
+ <b>Hello World Widget</b>
+ <ul id="data"/>
+ """
+ onmessage = """
+ $('<li/>').text(json.msg).prependTo('#data');
+ """
+
+<add to entry point>
+
+<rendering the widget>
+
+.. code-block:: python
+
+ @expose('mako:moksha.templates.widget')
+ def livewidget(self, *args, **kwargs):
+ tmpl_context.widget = moksha.get_widget('helloworld')
+ tmpl_context.moksha_socket = moksha.get_widget('moksha_socket')
+ return dict(options={})
+
+
+Creating a database model
+-------------------------
+
+Caching
+-------
13 years, 7 months
4 commits - demo/demo demo/setup.py docs/apps docs/main moksha/apps moksha/commands
by Luke Macken
demo/demo/consumer.py | 7 +++++
demo/demo/controllers/root.py | 39 +++++++++++++++++++++++++++++++++
demo/demo/model/__init__.py | 15 ++++++++++++
demo/demo/model/model.py | 12 ++++++++++
demo/demo/root.py | 12 ----------
demo/demo/template.mak | 8 ------
demo/demo/templates/model.mak | 7 +++++
demo/demo/templates/template.mak | 8 ++++++
demo/demo/widget.py | 6 +++--
demo/setup.py | 5 +++-
docs/apps/MokshaMenus.rst | 5 ----
docs/main/MokshaLabs.rst | 2 -
moksha/apps/menus/docs/MokshaMenus.rst | 5 ++++
moksha/commands/cli.py | 5 ++--
14 files changed, 105 insertions(+), 31 deletions(-)
New commits:
commit c1aca721ea7ce38eadd60e2f7f6ab5035524e944
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 8 15:31:04 2010 -0400
More updates to our Hello World demo app
diff --git a/demo/demo/consumer.py b/demo/demo/consumer.py
index c32fea6..10f4e3b 100644
--- a/demo/demo/consumer.py
+++ b/demo/demo/consumer.py
@@ -1,7 +1,14 @@
from moksha.api.hub.consumer import Consumer
+from demo.model import HelloWorldModel
class HelloWorldConsumer(Consumer):
topic = 'helloworld'
+ app = 'helloworld'
def consume(self, message):
self.log.info('Received message: ' + message['body']['msg'])
+
+ entry = HelloWorldModel()
+ entry.message = message['body']['msg']
+ self.DBSession.add(entry)
+ self.DBSession.commit()
diff --git a/demo/demo/controllers/__init__.py b/demo/demo/controllers/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/demo/demo/controllers/root.py b/demo/demo/controllers/root.py
new file mode 100644
index 0000000..1f77d96
--- /dev/null
+++ b/demo/demo/controllers/root.py
@@ -0,0 +1,39 @@
+import moksha
+
+from tg import expose, tmpl_context
+
+class Root(object):
+
+ @expose()
+ def index(self, *args, **kwargs):
+ return 'Hello World!'
+
+ @expose('mako:demo.templates.template')
+ def mako(self, *args, **kwargs):
+ """ An example controller method exposed with a Mako template """
+ return {'msg': 'Hello World!'}
+
+ @expose('mako:moksha.templates.widget')
+ def livewidget(self, *args, **kwargs):
+ tmpl_context.widget = moksha.get_widget('helloworld')
+ tmpl_context.moksha_socket = moksha.get_widget('moksha_socket')
+ return dict(options={})
+
+ @expose('mako:demo.templates.model')
+ def model(self, *args, **kwargs):
+ from demo.model import DBSession, HelloWorldModel
+ entries = DBSession.query(HelloWorldModel).all()
+ return dict(entries=entries)
+
+ @expose('mako:demo.templates.model')
+ def cached_model(self, *args, **kwargs):
+ from pylons import cache
+ mycache = cache.get_cache('helloworld')
+ entries = mycache.get_value(key='entries', createfunc=self._expensive_call,
+ expiretime=3600)
+ return dict(entries=entries)
+
+ def _expensive_call(self, *args, **kwargs):
+ from demo.model import DBSession, HelloWorldModel
+ entries = DBSession.query(HelloWorldModel).all()
+ return entries
diff --git a/demo/demo/model/__init__.py b/demo/demo/model/__init__.py
new file mode 100644
index 0000000..b425716
--- /dev/null
+++ b/demo/demo/model/__init__.py
@@ -0,0 +1,15 @@
+from zope.sqlalchemy import ZopeTransactionExtension
+from sqlalchemy.orm import scoped_session, sessionmaker
+from sqlalchemy.ext.declarative import declarative_base
+
+maker = sessionmaker(autoflush=True, autocommit=False,
+ extension=ZopeTransactionExtension())
+DBSession = scoped_session(maker)
+DeclarativeBase = declarative_base()
+metadata = DeclarativeBase.metadata
+
+def init_model(engine):
+ print "init_model(%s)" % engine
+ DBSession.configure(bind=engine)
+
+from model import HelloWorldModel
diff --git a/demo/demo/model/model.py b/demo/demo/model/model.py
new file mode 100644
index 0000000..0f8dbf7
--- /dev/null
+++ b/demo/demo/model/model.py
@@ -0,0 +1,12 @@
+from datetime import datetime
+from sqlalchemy import Integer, Text, DateTime, Column
+from demo.model import DeclarativeBase
+
+class HelloWorldModel(DeclarativeBase):
+ __tablename__ = 'helloworld'
+
+ id = Column(Integer, autoincrement=True, primary_key=True)
+
+ message = Column(Text)
+
+ timestamp = Column(DateTime, default=datetime.now)
diff --git a/demo/demo/root.py b/demo/demo/root.py
deleted file mode 100644
index 3574b84..0000000
--- a/demo/demo/root.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from tg import expose
-
-class Root(object):
-
- @expose()
- def index(self, *args, **kwargs):
- return 'Hello World!'
-
- @expose('mako:demo.template')
- def mako(self, *args, **kwargs):
- """ An example controller method exposed with a Mako template """
- return {'msg': 'Hello World!'}
diff --git a/demo/demo/template.mak b/demo/demo/template.mak
deleted file mode 100644
index 2010e44..0000000
--- a/demo/demo/template.mak
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
- <head>
- <title>${msg}</title>
- </head>
- <body>
- ${msg}
- </body>
-</html>
diff --git a/demo/demo/templates/__init__.py b/demo/demo/templates/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/demo/demo/templates/model.mak b/demo/demo/templates/model.mak
new file mode 100644
index 0000000..af50fed
--- /dev/null
+++ b/demo/demo/templates/model.mak
@@ -0,0 +1,7 @@
+<h1>Entries in the HelloWorld model</h1>
+
+<ul>
+ % for entry in entries[::-1]:
+ <li>${str(entry.id)} - ${entry.message} - ${str(entry.timestamp)}</li>
+ % endfor
+</ul>
diff --git a/demo/demo/templates/template.mak b/demo/demo/templates/template.mak
new file mode 100644
index 0000000..2010e44
--- /dev/null
+++ b/demo/demo/templates/template.mak
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>${msg}</title>
+ </head>
+ <body>
+ ${msg}
+ </body>
+</html>
diff --git a/demo/demo/widget.py b/demo/demo/widget.py
index 631ea07..f9d0ad4 100644
--- a/demo/demo/widget.py
+++ b/demo/demo/widget.py
@@ -4,8 +4,8 @@ class HelloWorldWidget(LiveWidget):
topic = "helloworld"
template = """
<b>Hello World Widget</b>
- <div id="data"/>
+ <ul id="data"/>
"""
onmessage = """
- $('#data').append(json.msg).append('<br/>');
+ $('<li/>').text(json.msg).prependTo('#data');
"""
diff --git a/demo/setup.py b/demo/setup.py
index 8cc041e..10868ef 100644
--- a/demo/setup.py
+++ b/demo/setup.py
@@ -16,7 +16,10 @@ setup(
entry_points="""
[moksha.root]
- root = demo.root:Root
+ root = demo.controllers.root:Root
+
+ [moksha.application]
+ helloworld = demo.controllers.root:Root
[moksha.producer]
helloworld = demo.producer:HelloWorldProducer
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
index 2563a17..f44ce2d 100644
--- a/moksha/commands/cli.py
+++ b/moksha/commands/cli.py
@@ -61,8 +61,8 @@ class MokshaCLI(object):
orbited += ['-c', '/etc/moksha/orbited.cfg']
self._exec(*orbited)
- self._exec('moksha-hub')
self._exec('paster', 'serve', get_moksha_config_path())
+ self._exec('moksha-hub')
def list(self):
""" List all available apps, widgets, producers and consumers """
commit 16bbeb391be3b4116a51b2b0bfaa239c38aa81e0
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 8 13:54:12 2010 -0400
Trivial formatting tweak in the live widget demo
diff --git a/demo/demo/widget.py b/demo/demo/widget.py
index 32b9aff..631ea07 100644
--- a/demo/demo/widget.py
+++ b/demo/demo/widget.py
@@ -6,4 +6,6 @@ class HelloWorldWidget(LiveWidget):
<b>Hello World Widget</b>
<div id="data"/>
"""
- onmessage = "$('#data').append(json.msg).append('<br/>');"
+ onmessage = """
+ $('#data').append(json.msg).append('<br/>');
+ """
commit d3aac8496ef2b4a10c09c8eb35d6c1d851ff8cc8
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 8 13:53:49 2010 -0400
Add the current directory to pkg_resources.working_set in the moksha cli
diff --git a/moksha/commands/cli.py b/moksha/commands/cli.py
index a1ffa56..2563a17 100644
--- a/moksha/commands/cli.py
+++ b/moksha/commands/cli.py
@@ -99,7 +99,6 @@ class MokshaCLI(object):
reactor.run()
-
def get_parser():
usage = 'usage: %prog [command]'
parser = OptionParser(usage, description=__doc__)
@@ -115,6 +114,8 @@ def get_parser():
def main():
parser = get_parser()
opts, args = parser.parse_args()
+ pkg_resources.working_set.add_entry(os.getcwd())
+
moksha = MokshaCLI()
logging.basicConfig(level=logging.INFO, format=
commit c32e12fcfa0e1c6b54a9acc4db94c79d73e5f21a
Author: Luke Macken <lmacken(a)redhat.com>
Date: Fri Oct 8 13:23:32 2010 -0400
Move our MokshaMenu's docs out into the app itself.
Eventually, Moksha should handle compiling docs for apps, but in the mean time
this doc requires the moksha.menus app, which is not installed by default.
diff --git a/docs/apps/MokshaMenus.rst b/docs/apps/MokshaMenus.rst
deleted file mode 100644
index cf14e5d..0000000
--- a/docs/apps/MokshaMenus.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-.. automodule:: moksha.apps.menus.widgets
-
-.. widgetbrowser:: moksha.apps.menus.default.MokshaDefaultMenu
- :tabs: demo, source
- :size: large
diff --git a/docs/main/MokshaLabs.rst b/docs/main/MokshaLabs.rst
index d6bdc41..1c74b16 100644
--- a/docs/main/MokshaLabs.rst
+++ b/docs/main/MokshaLabs.rst
@@ -10,6 +10,6 @@ The Moksha Labs is an experimental R&D playground for reusable apps & widgets.
Feeds
MokshaContainerWidgets
Connectors
- ../apps/MokshaMenus
Blueprint
+ #../apps/MokshaMenus
diff --git a/moksha/apps/menus/docs/MokshaMenus.rst b/moksha/apps/menus/docs/MokshaMenus.rst
new file mode 100644
index 0000000..cf14e5d
--- /dev/null
+++ b/moksha/apps/menus/docs/MokshaMenus.rst
@@ -0,0 +1,5 @@
+.. automodule:: moksha.apps.menus.widgets
+
+.. widgetbrowser:: moksha.apps.menus.default.MokshaDefaultMenu
+ :tabs: demo, source
+ :size: large
13 years, 7 months