development.ini | 2 - docs/index.rst | 4 +- docs/main/Feeds.rst | 1 docs/main/MokshaApplications.rst | 58 +++++++++++++++++++------------------- moksha/__init__.py | 16 +++++----- moksha/api/menus/default.py | 2 - moksha/api/menus/widgets.py | 2 - moksha/api/streams/datastream.py | 2 - moksha/api/widgets/feed/feed.py | 16 +++++++--- moksha/config/app_cfg.py | 3 + moksha/middleware/middleware.py | 4 +- moksha/streams/demo/demostream.py | 7 +++- orbited.cfg | 4 +- 13 files changed, 68 insertions(+), 53 deletions(-)
New commits: commit 1b82ac582b4cdc0be8918dcb662bf835141e9395 Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:35:51 2009 -0500
Cleanly close our feed objects in our demo data stream
diff --git a/moksha/api/widgets/feed/feed.py b/moksha/api/widgets/feed/feed.py index 9015575..b78337a 100644 --- a/moksha/api/widgets/feed/feed.py +++ b/moksha/api/widgets/feed/feed.py @@ -29,7 +29,8 @@ log = logging.getLogger(__name__) # is unavailable. By default, it will try and use the centralized # moksha.feed_cache, which is setup by the middleware, but will gracefully # fallback to this cache. -cache = None +feed_storage = None +feed_cache = None
class Feed(Widget): """ A powerful Feed object. @@ -95,10 +96,11 @@ class Feed(Widget): else: # MokshaMiddleware not running, so setup our own feed cache. # This allows us to use this object outside of WSGI requests. - global cache - if not cache: - cache = Cache(Shove('sqlite:///feeds.db', compress=True)) - feed = cache.fetch(url) + global feed_cache, feed_storage + if not feed_cache: + feed_storage = Shove('sqlite:///feeds.db', compress=True) + feed_cache = Cache(feed_storage) + feed = feed_cache.fetch(url) if not (200 <= feed.status < 400): log.warning('Got %s status from %s: %s' % ( feed.status, url, feed.headers.get('status'))) @@ -135,3 +137,7 @@ class Feed(Widget): else: for entry in self.iterentries(d): d['entries'].append(entry) + + def close(self): + global feed_storage + feed_storage.close() diff --git a/moksha/streams/demo/demostream.py b/moksha/streams/demo/demostream.py index ab47a6b..0335362 100644 --- a/moksha/streams/demo/demostream.py +++ b/moksha/streams/demo/demostream.py @@ -19,7 +19,8 @@ class MokshaDemoDataStream(PollingDataStream): n = 0
# Feed demo specific variables - feed_entries = Feed(url='http://doggdot.us/rss%27).entries() + feed = Feed(url='http://doggdot.us/rss') + feed_entries = feed.entries() i = 0
def poll(self): @@ -74,3 +75,7 @@ class MokshaDemoDataStream(PollingDataStream): }]
self.send_message('flot_demo', flot_data) + + def stop(self): + self.feed.close() + super(MokshaDemoDataStream, self).stop()
commit 919fdb367667ab81348c07fed575aeac085d410c Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:24:35 2009 -0500
Ensure we compress our Shove cache
diff --git a/moksha/api/widgets/feed/feed.py b/moksha/api/widgets/feed/feed.py index 864b2fe..9015575 100644 --- a/moksha/api/widgets/feed/feed.py +++ b/moksha/api/widgets/feed/feed.py @@ -97,7 +97,7 @@ class Feed(Widget): # This allows us to use this object outside of WSGI requests. global cache if not cache: - cache = Cache(Shove('sqlite:///feeds.db')) + cache = Cache(Shove('sqlite:///feeds.db', compress=True)) feed = cache.fetch(url) if not (200 <= feed.status < 400): log.warning('Got %s status from %s: %s' % (
commit 2c7360e6a9093d313d03964c151c6b729b0ba91b Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:23:54 2009 -0500
Properly close the hub in the datastream
diff --git a/moksha/api/streams/datastream.py b/moksha/api/streams/datastream.py index ddd4577..5b476f1 100644 --- a/moksha/api/streams/datastream.py +++ b/moksha/api/streams/datastream.py @@ -20,7 +20,7 @@ class DataStream(object): log.error('Cannot send message: %s' % e)
def stop(self): - self.hub.stop() + self.hub.close()
class PollingDataStream(DataStream):
commit 0d0fe11d50d029305077656ebdb9c760727f7425 Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:10:54 2009 -0500
Document modifications. Add instructions for mounting a WSGI app
diff --git a/docs/index.rst b/docs/index.rst index 6fb323c..e41ef10 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -78,8 +78,8 @@ Widgets
main/MokshaModel
-Middleware ----------- +WSGI Middleware +---------------
.. toctree:: :maxdepth: 1 diff --git a/docs/main/Feeds.rst b/docs/main/Feeds.rst index 7c580a1..ccbe062 100644 --- a/docs/main/Feeds.rst +++ b/docs/main/Feeds.rst @@ -1,3 +1,4 @@ +===== Feeds =====
diff --git a/docs/main/MokshaApplications.rst b/docs/main/MokshaApplications.rst index 70d2d7e..d6aa089 100644 --- a/docs/main/MokshaApplications.rst +++ b/docs/main/MokshaApplications.rst @@ -1,43 +1,45 @@ -Moksha Applications -=================== +Moksha Plugins +==============
-Creating a moksha application is a as easy as creating a new ToscaWidget or -TurboGears2/Pylons project. - -Moksha entry points -------------------- +When the :class:`moksha.middleware.MokshaMiddleware` is loaded, it will +automatically load all applications and widgets from those entry points, +and store them in ``moksha.apps`` and ``moksha._widgets`` dictionaries. +These can then be accessed at any time by any application or widget during +any request.
-Moksha loads all applications and widgets from the ``moksha.application`` and -``moksha.widget`` setuptools entry point. This allows for dynamic discovery -of moksha applications just by pointing to your Root Controller, or ToscaWidget -in your project's `setup.py`. +Mounting an existing WSGI application +-------------------------------------
-Here is an example of a bare-bones setup.py, and how to integrate it with -Moksha. +You can mount an existing WSGI application by pointing to it +in the ``setup.py`` on the ``[moksha.wsgiapp]`` entry-point.
.. code-block:: python
- from setuptools import setup + [moksha.wsgiapp] + mywsgiapp = mywsgiapp.wsgiapp:MyWSGIApplication
- setup( - name='myproject', - entry_points=""" +Your WSGI application will then be accessable via ``/appz/mywsgiapp`` in Moksha.
- [moksha.widget] - mywidget = myproject.mywidgets:MyWidget +Using an existing TurboGears application +-------------------------------------------
- [moksha.application] - myapp = myproject.controllers.root:RootController +You can easily mount TurboGears Controllers within Moksha by pointing to them in +your ``setup.py`` under the ``[moksha.application]`` entry-point.
- """ - ) +.. code-block:: python
+ [moksha.application] + myapp = myapplication.controllers.root:RootController
-When the :class:`moksha.middleware.MokshaMiddleware` is loaded, it will -automatically load all applications and widgets from those entry points, -and store them in ``moksha.apps`` and ``moksha._widgets`` dictionaries. -These can then be accessed at any time by any application or widget during -any request. +Installing a ToscaWidget +------------------------ + +You can plug an existing ToscaWidget into Moksha by adding it to the ``[moksha.widget]`` entry-point. + +.. code-block:: python + + [moksha.widget] + jquery = tw.jquery:jquery_js
Configuration -------------
commit a906f7171fc9c27635cbdac528849a06bc850ab1 Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:10:22 2009 -0500
Properly close our feed_storage upon shutdown, so entries can be flushed
diff --git a/moksha/__init__.py b/moksha/__init__.py index 42bcb69..c3b5e92 100644 --- a/moksha/__init__.py +++ b/moksha/__init__.py @@ -23,12 +23,9 @@ menus = None stomp = StackedObjectProxy()
def get_widget(name): - """ Get a widget by name. - - This method returns a dictionary in the following format: - - { 'name': 'widgetname', - 'widget': <Widget instance>, - 'path': '/path/to/widget' } - """ + """ Get a widget instance by name """ return _widgets[name]['widget'] + +def shutdown(): + """ Called when Moksha shuts down """ + feed_storage.close() diff --git a/moksha/config/app_cfg.py b/moksha/config/app_cfg.py index 964909c..c4fd658 100644 --- a/moksha/config/app_cfg.py +++ b/moksha/config/app_cfg.py @@ -40,3 +40,6 @@ base_config.profile = False
# Enable repoze.squeeze resource squeezing middleware base_config.squeeze = False + +from moksha import shutdown +base_config.call_on_shutdown.append(shutdown)
commit 56c31ca004ea32ce3c630a468837cb74e873bea3 Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:08:46 2009 -0500
Put our feed_storage in moksha.__init__.py, and pass it the compress argument
diff --git a/moksha/__init__.py b/moksha/__init__.py index 32da334..42bcb69 100644 --- a/moksha/__init__.py +++ b/moksha/__init__.py @@ -4,6 +4,9 @@ from paste.registry import StackedObjectProxy # The central feed cache, used by the Feed widget. feed_cache = None
+# A dict-like persistent backing store +feed_storage = None + # All loaded moksha applications apps = None
diff --git a/moksha/middleware/middleware.py b/moksha/middleware/middleware.py index d360762..156a7ba 100644 --- a/moksha/middleware/middleware.py +++ b/moksha/middleware/middleware.py @@ -68,8 +68,8 @@ class MokshaMiddleware(object): self.load_models() self.load_menus()
- self.feed_storage = Shove(config['feed_cache']) - moksha.feed_cache = Cache(self.feed_storage) + moksha.feed_storage = Shove(config['feed_cache'], compress=True) + moksha.feed_cache = Cache(moksha.feed_storage)
def __call__(self, environ, start_response): self.register_stomp(environ)
commit 48bf8c5d4ee63098dacc2fd32886e2a39d9bec38 Author: Luke Macken lmacken@redhat.com Date: Mon Feb 9 17:07:49 2009 -0500
Utilize the same feed cache as our Feed object does if the middleware isn't available
diff --git a/development.ini b/development.ini index f925940..2c41abb 100644 --- a/development.ini +++ b/development.ini @@ -19,7 +19,7 @@ error_email_from = paste@localhost ##
# Where to store the feed caches. -feed_cache = sqlite:///%(here)s/feeds.sqlite +feed_cache = sqlite:///%(here)s/feeds.db #feed_cache = %(here)s/data/feeds
# Where to initialize and store our application databases. %s is the app name.
commit 12d761635a2e0f2600c864ca490a47c39961261e Author: Luke Macken lmacken@redhat.com Date: Fri Feb 6 19:54:40 2009 -0500
This issue seemed to resolve itself when I moved my production deployment from paster to mod_wsgi
diff --git a/moksha/api/menus/widgets.py b/moksha/api/menus/widgets.py index 48db2e9..b776095 100644 --- a/moksha/api/menus/widgets.py +++ b/moksha/api/menus/widgets.py @@ -113,8 +113,6 @@ class MokshaContextualMenu(MokshaMenuBase): menus.append((menu.lower().replace(' ', ''), menu)) d.menus = menus
- # @@: this yields $("document") on python 2.4... we may need to - # do this stuff in the template... or can we pass JSSource to add_call? self.add_call(jQuery(js_callback('document')).buildContextualMenu({ 'template': d.callback, 'menuWidth': d.menuWidth,
commit bff6894dbc3e71a868d4efa1af4b87f547c2f23f Author: Luke Macken lmacken@redhat.com Date: Fri Feb 6 19:51:59 2009 -0500
Open fedora menu links in new windows
diff --git a/moksha/api/menus/default.py b/moksha/api/menus/default.py index 14ecd33..356e692 100644 --- a/moksha/api/menus/default.py +++ b/moksha/api/menus/default.py @@ -91,5 +91,5 @@ class MokshaDefaultMenu(MokshaMenu): <a rel="separator"></a> """ for title, url in links.items(): - menu += '<a href="%s">%s</a>' % (url, title) + menu += '<a href="%s" target="_blank">%s</a>' % (url, title) return menu
commit 5c0baf3eef935b03857c6a940f47c4c8abbe8c1b Author: Luke Macken lmacken@redhat.com Date: Fri Feb 6 19:47:17 2009 -0500
Use the select reactor in Orbited to begin with, so we can work out of the box on Macs.
Ideally, we should be using the kqueue reactor on Darwin, but I have no had any luck getting it working. If someone can do it, please do so.
diff --git a/orbited.cfg b/orbited.cfg index 6006d84..9c72ef8 100644 --- a/orbited.cfg +++ b/orbited.cfg @@ -14,8 +14,8 @@ stomp://:61613 # Enables the use of the proxy through the Orbited.TCPSocket JavaScript object. proxy.enabled = 1
-reactor=epoll # Linux -#reactor=select # Windows +reactor=select # All platforms +#reactor=epoll # Linux #reactor=kqueue # OS X/FreeBSD
#session.ping_interval = 30