moksha/widgets
by Luke Macken
moksha/widgets/container/container.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 90d29b79c07068189b9dbedb2352c3beb8580994
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 00:56:41 2009 -0500
Make our default container a bit wider, to accomidate for our flot demo widget
diff --git a/moksha/widgets/container/container.py b/moksha/widgets/container/container.py
index 721d585..9499c57 100644
--- a/moksha/widgets/container/container.py
+++ b/moksha/widgets/container/container.py
@@ -38,7 +38,7 @@ class MokshaContainer(Widget):
skin = 'skin3' # skin[1-7]
# Pixel tweaking
- width = 400
+ width = 430
left = 170
top = 270
15 years, 4 months
moksha/api
by Luke Macken
moksha/api/widgets/containers/dashboardcontainer.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
New commits:
commit 6414d70d8c1bfd1a89be9d2ca8cbcbe77fc7a5bc
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 00:26:51 2009 -0500
Don't pull in jQuery + jQuery UI in our DashboardContainer
diff --git a/moksha/api/widgets/containers/dashboardcontainer.py b/moksha/api/widgets/containers/dashboardcontainer.py
index 0dde052..04e56a4 100644
--- a/moksha/api/widgets/containers/dashboardcontainer.py
+++ b/moksha/api/widgets/containers/dashboardcontainer.py
@@ -24,9 +24,6 @@ applist_widget = AppListWidget('applist');
class DashboardContainer(Widget):
template = 'mako:moksha.api.widgets.containers.templates.dashboardcontainer'
- css = []
- javascript = [jquery_js, layout_js, ui_core_js, ui_draggable_js,
- ui_droppable_js, ui_sortable_js]
config_key = None
layout = []
@@ -47,4 +44,4 @@ class DashboardContainer(Widget):
d['layout'] = l
d['applist_widget'] = applist_widget
- return d
\ No newline at end of file
+ return d
15 years, 4 months
docs/code_ext.py docs/main
by Luke Macken
docs/code_ext.py | 4 ++--
docs/main/GettingStarted.rst | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
New commits:
commit dfd1ff048bab17dca085188553742a763158b200
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 00:20:02 2009 -0500
Don't require pysvn and mercurial to build docs anymore
diff --git a/docs/code_ext.py b/docs/code_ext.py
index 349c137..beb4f85 100755
--- a/docs/code_ext.py
+++ b/docs/code_ext.py
@@ -21,9 +21,7 @@ from docutils.statemachine import ViewList
from sphinx import util
-import pysvn
import nose
-from mercurial import hg, ui
beginmarker_re = re.compile(r'##\{(?P<section>.+)}')
@@ -73,6 +71,7 @@ def search(source, section):
class HgClient:
""" Class that represents a Mercurial client """
def __init__(self, path):
+ from mercurial import hg, ui
self.repo = hg.repository(ui.ui(interactive=False), path=path)
def get_file(self, path, revision='tip'):
@@ -82,6 +81,7 @@ class HgClient:
class SVNClient:
""" Class that represents a Subversion client """
def __init__(self):
+ import pysvn
self.client = pysvn.Client()
def get_file(self, path, revision='HEAD'):
diff --git a/docs/main/GettingStarted.rst b/docs/main/GettingStarted.rst
index f865d07..4c0c113 100644
--- a/docs/main/GettingStarted.rst
+++ b/docs/main/GettingStarted.rst
@@ -24,7 +24,7 @@ You'll need the `virtualenv <http://pypi.python.org/pypi/virtualenv>`_ package.
.. code-block:: bash
- # yum -y install python-virtualenv pysvn mercurial PyOpenSSL python-memcached
+ # yum -y install python-virtualenv PyOpenSSL python-memcached
The `start-moksha` script mentioned below should install all of the necessary
dependencies. However, it will attempt to compile a few things, such as lxml. So, you may need to install some additional dependencies like `libxml2` and `libxslt` in order to build it. If you're using yum, you can easily install all of the build requirements by doing:
15 years, 4 months
setup.py
by Luke Macken
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 8cc785d8e2423ae72d1e1186e1964abc8815a0d8
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 23:55:40 2009 -0500
Disable the feed stream by default, since it is a bit noisy :)
diff --git a/setup.py b/setup.py
index 0d08282..7aa603d 100644
--- a/setup.py
+++ b/setup.py
@@ -51,7 +51,7 @@ setup(
[moksha.stream]
demo = moksha.streams.demo:MokshaDemoDataStream
#livegraph = moksha.examples.livegraph:LiveGraphDataStream
- feed = moksha.streams.feed:FeedStream
+ #feed = moksha.streams.feed:FeedStream
#[moksha.consumer]
#moksha = moksha.hub.hub:MokshaConsumer
15 years, 4 months
moksha/streams
by Luke Macken
moksha/streams/feed/feedstream.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
New commits:
commit ae6d337dac41e20c9b04ee34b0830c3080216d18
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 23:48:42 2009 -0500
Handle keys that don't exist in our feed cache
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index a1e6683..9ac2f6d 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -162,7 +162,10 @@ class FeederProtocol(object):
return feed
def get_feed(self, addr):
- return feed_storage[addr][1]
+ try:
+ return feed_storage[addr][1]
+ except KeyError:
+ return None
def process_feed(self, parsed_feed, addr, olddata):
""" Process the parsed feed.
15 years, 4 months
moksha/streams
by Luke Macken
moksha/streams/feed/feedstream.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit c32f083a8259db2ef329e7f0f101804cd1e2461b
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 23:42:35 2009 -0500
Don't pull in the conditional_get_page method
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index 11496f7..a1e6683 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -38,7 +38,7 @@ from shove import Shove
from tg import config
from moksha.hub import MokshaHub
-from moksha.hub.http import conditional_get_page
+#from moksha.hub.http import conditional_get_page
from moksha.api.streams import PollingDataStream
log = logging.getLogger('moksha.hub')
15 years, 4 months
moksha/hub
by Luke Macken
moksha/hub/reactor.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 744dec49050bb595509535a66a2dc26a2c687d38
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 23:40:20 2009 -0500
Catch ImportErrors in our reactor setup
diff --git a/moksha/hub/reactor.py b/moksha/hub/reactor.py
index 8e919ce..0ab471a 100644
--- a/moksha/hub/reactor.py
+++ b/moksha/hub/reactor.py
@@ -32,7 +32,7 @@ try:
elif 'win' in sys.platform:
from twisted.internet import iocpreactor
iocpreactor.install()
-except AssertionError: # reactor already installed
+except (ImportError, AssertionError): # reactor already installed
pass
from twisted.internet import reactor
15 years, 4 months
11 commits - moksha/api moksha/hub moksha/lib moksha/streams start-moksha
by Luke Macken
moksha/api/streams/datastream.py | 4 -
moksha/api/widgets/feed/feed.py | 6 -
moksha/api/widgets/feed/live.py | 6 +
moksha/hub/hub.py | 19 +++-
moksha/hub/reactor.py | 6 -
moksha/lib/cache.py | 11 ++
moksha/streams/feed/feedstream.py | 152 +++++++++++++++++---------------------
start-moksha | 1
8 files changed, 106 insertions(+), 99 deletions(-)
New commits:
commit 1dd06e1be96beb0088e58e06e9e775063e14b6ec
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 23:11:08 2009 -0500
Fix a bug on platform detection on Mac OSX
diff --git a/moksha/hub/reactor.py b/moksha/hub/reactor.py
index c92ab1b..8e919ce 100644
--- a/moksha/hub/reactor.py
+++ b/moksha/hub/reactor.py
@@ -26,12 +26,12 @@ try:
if 'linux' in sys.platform:
from twisted.internet import epollreactor
epollreactor.install()
- elif 'win' in sys.platform:
- from twisted.internet import iocpreactor
- iocpreactor.install()
elif 'freebsd' in sys.platform or 'darwin' in sys.platform:
from twisted.internet import kqreactor
kqreactor.install()
+ elif 'win' in sys.platform:
+ from twisted.internet import iocpreactor
+ iocpreactor.install()
except AssertionError: # reactor already installed
pass
commit ad33591fa573ea41a1dd083b21c9895dfc9a339b
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:24:27 2009 -0500
Have our MokshaHub.send_message support lists of topics.
diff --git a/moksha/hub/hub.py b/moksha/hub/hub.py
index e41ffa3..d0d9f3e 100644
--- a/moksha/hub/hub.py
+++ b/moksha/hub/hub.py
@@ -66,17 +66,22 @@ class MokshaHub(StompHub, AMQPHub):
def send_message(self, topic, message, jsonify=True):
""" Send a message to a specific topic.
- :topic: The stop to send the message to
+ :topic: A topic or list of topics to send the message to.
:message: The message body. Can be a string, list, or dict.
:jsonify: To automatically encode non-strings to JSON
"""
- if jsonify and not isinstance(message, basestring):
- message = json.encode(message)
- if self.amqp_broker:
- AMQPHub.send_message(self, topic, message, routing_key=topic)
- elif self.stomp_broker:
- StompHub.send_message(self, topic, message)
+ if not isinstance(topic, list):
+ topics = [topic]
+ else:
+ topics = topic
+ for topic in topics:
+ if jsonify and not isinstance(message, basestring):
+ message = json.encode(message)
+ if self.amqp_broker:
+ AMQPHub.send_message(self, topic, message, routing_key=topic)
+ elif self.stomp_broker:
+ StompHub.send_message(self, topic, message)
def close(self):
if self.amqp_broker:
commit ce3aadd4a503b9b374d3345e75d5968b67c910d8
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:22:06 2009 -0500
Send our feed messages to two topics for now
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index eb72445..11496f7 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -200,8 +200,8 @@ class FeederProtocol(object):
entry_title = entry.get('title', '[No Title]')
channel_link = entry.get('channel', {'link': addr})['link']
if entry['title'] not in oldtitles:
- log.info('New feed entry found: %' % entry['title'])
- self.hub.send_message('feed.%s' % channel_link,
+ log.info('New feed entry found: %s' % entry['title'])
+ self.hub.send_message(['feed.%s' % channel_link, 'feeds'],
{'title': entry_title, 'link': entry.get('link')})
def get_page(self, data, args):
commit c06cd189c3a077b613a0f5b5b38f4d2388b39329
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:15:32 2009 -0500
SymbolType has been giving people problems
diff --git a/start-moksha b/start-moksha
index 269bf9d..fdb7875 100755
--- a/start-moksha
+++ b/start-moksha
@@ -14,6 +14,7 @@ if [ ! $VIRTUAL_ENV ]; then
easy_install -i http://www.turbogears.org/2.0/downloads/current/index tg.devtools
pushd moksha/widgetbrowser; python setup.py develop; popd
easy_install "tw.jquery==dev"
+ easy_install SymbolType
else
source tg2env/bin/activate
fi
commit 328b015e5887d55ca4391421c3bff602c38ce6d5
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:15:20 2009 -0500
Run the FeedStreamer every 10 minutes
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index 24e6a99..eb72445 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -263,7 +263,7 @@ class FeedStream(PollingDataStream):
then Moksha will automatically handle polling it. Upon new entries,
AMQP messages will be sent to the `feeds.$URL` queue.
"""
- frequency = timedelta(minutes=5)
+ frequency = timedelta(minutes=10)
def poll(self):
""" Poll all feeds in our feed cache """
commit 9af4dde6ddb10852860ab090a4e55b293756fee8
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:13:09 2009 -0500
Many FeedStreamer improvements, including the sending of notifications for new entries
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index 0225e11..24e6a99 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -30,13 +30,16 @@ from twisted.web import client
from twisted.web.client import HTTPPageGetter, HTTPClientFactory
from twisted.internet import reactor, protocol, defer, ssl
from twisted.web import error
+from twisted.internet import protocol, defer
+
from datetime import timedelta, datetime
from feedcache import Cache
from shove import Shove
from tg import config
+from moksha.hub import MokshaHub
+from moksha.hub.http import conditional_get_page
from moksha.api.streams import PollingDataStream
-from moksha.lib.helpers import trace
log = logging.getLogger('moksha.hub')
@@ -46,12 +49,12 @@ feed_cache = Cache(feed_storage)
class ConditionalHTTPPageGetter(HTTPPageGetter):
def handleStatus_200(self):
- """ If we're good, try recording the last-modified header """
+ """ Attempt to save the last-modified header """
if self.headers.has_key('last-modified'):
self.factory.lastModified(self.headers['last-modified'])
def handleStatus_304(self):
- """ Close connection """
+ """ Close the connection """
self.factory.notModified()
self.transport.loseConnection()
@@ -61,8 +64,7 @@ class ConditionalHTTPClientFactory(HTTPClientFactory):
protocol = ConditionalHTTPPageGetter
def __init__(self, url, method='GET', postdata=None, headers=None,
- agent="Moksha Feed Streamer", timeout=0, cookies=None,
- followRedirect=1):
+ agent=None, timeout=0, cookies=None, followRedirect=1):
self.url = url
@@ -91,9 +93,9 @@ class ConditionalHTTPClientFactory(HTTPClientFactory):
try:
feed_storage[self.url] = (t, parsed_feed)
- except:
+ except Exception, e:
log.error("Unable to store parsed_feed: %r" % parsed_feed)
- raise
+ log.exception(e)
def notModified():
if self.waiting:
@@ -119,11 +121,10 @@ class FeederProtocol(object):
def __init__(self):
self.parsed = 1
- self.with_errors = 0
- self.error_list = []
+ self.hub = MokshaHub()
def is_cached(self, site):
- already_got = feed_storage.get(site[0])
+ already_got = feed_storage.get(site)
if already_got:
elapsed_time = time.time() - already_got[0]
if elapsed_time < self.max_age:
@@ -136,8 +137,6 @@ class FeederProtocol(object):
def on_error(self, traceback, extra_args):
log.error(extra_args)
log.exception(traceback)
- self.with_errors += 1
- self.error_list.append(extra_args)
def get_feed_from_cache(self, data, key=None):
""" Return feed data from the cache based on a given ``key`` """
@@ -162,72 +161,70 @@ class FeederProtocol(object):
feed_storage[addr] = (time.time(), feed)
return feed
- def process_feed(self, parsed_feed, addr):
+ def get_feed(self, addr):
+ return feed_storage[addr][1]
+
+ def process_feed(self, parsed_feed, addr, olddata):
+ """ Process the parsed feed.
+
+ If `olddata` is provided, this method will look for new feed entries,
+ and send notifications to the `feed.$FEED_URL` MokshaHub Topic.
+
+ :param parsed_feed: A parsed :mod:`feedcache` feed
+ :param addr: The URL of the feed
+ :param olddata: The cached feed data
+ """
if not parsed_feed:
log.error("Cannot process %r feed for %s" % (parsed_feed, addr))
return
+
chan = parsed_feed.get('channel', None)
if chan:
log.debug(chan.get('title', ''))
- # print chan.get('link', '')
- # #print chan.get('tagline', '')
- # print chan.get('description','')
- #print "-"*20
- #items = parsed_feed.get('items', None)
- #if items:
- # for item in items:
- # print '\tTitle: ', item.get('title','')
- # print '\tDate: ', item.get('date', '')
- # print '\tLink: ', item.get('link', '')
- # print '\tDescription: ', item.get('description', '')
- # print '\tSummary: ', item.get('summary','')
- # print "-"*20
- #print "got",addr
- #print "="*40
- return parsed_feed
-
- ## @@ post processing
- for url in feed_storage:
- olddata = feed_storage[url][1].copy()
- newdata = feed_cache.fetch(url) #, force_update=True)
+
+ # Previous data provided; look for new entries.
+ if olddata:
+ oldtitles = [entry.get('title') for entry in olddata['entries']]
+ new_entries = parsed_feed.get('entries', [{}])
+ if not len(new_entries):
+ log.warning('Feed contains empty entries: %s' % addr)
+ return
+
# If there are no new entries, move on...
- if newdata['entries'][0]['title'] == olddata['entries'][0]['title']:
- log.debug('No feed changes for %s' % url)
- del(olddata)
- continue
- oldtitles = [entry['title'] for entry in olddata['entries']]
- for entry in newdata['entries'][::-1]:
- # If we haven't seen this entry yet...
+ newtitle = new_entries[0].get('title', None)
+ if newtitle == oldtitles[0]:
+ return
+
+ # Send notifications for each new entry
+ for entry in new_entries[::-1]:
+ entry_title = entry.get('title', '[No Title]')
+ channel_link = entry.get('channel', {'link': addr})['link']
if entry['title'] not in oldtitles:
- # Send a message to the feed's topic
- print "New entry:", entry['title']
- self.send_message('feed.%s' % entry.channel.link,
- {'title': entry['title'], 'link': entry['link']})
- else:
- print "Dupe entry", entry['title']
-
+ log.info('New feed entry found: %' % entry['title'])
+ self.hub.send_message('feed.%s' % channel_link,
+ {'title': entry_title, 'link': entry.get('link')})
def get_page(self, data, args):
return conditional_get_page(args, timeout=self.timeout)
- def print_status(self, data=None):
- pass
-
def start(self, data=None):
d = defer.succeed(True)
for feed in data:
+ olddata = None
if self.is_cached(feed):
- d.addCallback(self.get_feed_from_cache, feed[0])
- d.addErrback(self.on_error, (feed[0], 'fetching from cache'))
+ d.addCallback(self.get_feed_from_cache, feed)
+ d.addErrback(self.on_error, (feed, 'fetching from cache'))
else:
- d.addCallback(self.get_page, feed[0])
- d.addErrback(self.on_error, (feed[0], 'fetching'))
- d.addCallback(self.parse_feed, feed[0])
- d.addErrback(self.on_error, (feed[0], 'parsing'))
- d.addCallback(self.store_feed, feed[0])
- d.addErrback(self.on_error, (feed[0], 'storing'))
- d.addCallback(self.process_feed, feed[0])
- d.addErrback(self.on_error, (feed[0], 'processing'))
+ d.addCallback(self.get_page, feed)
+ d.addErrback(self.on_error, (feed, 'fetching'))
+ d.addCallback(self.parse_feed, feed)
+ d.addErrback(self.on_error, (feed, 'parsing'))
+ olddata = self.get_feed(feed)
+ d.addCallback(self.store_feed, feed)
+ d.addErrback(self.on_error, (feed, 'storing'))
+ d.addCallback(self.process_feed, feed, olddata)
+ d.addErrback(self.on_error, (feed, 'processing'))
+ del(olddata)
return d
@@ -266,35 +263,24 @@ class FeedStream(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 = 5 # seconds
- running = False
+ frequency = timedelta(minutes=5)
def poll(self):
- """ Poll all known feeds.
+ """ Poll all feeds in our feed cache """
+ log.debug('FeedStream.poll()')
- - Iterate over all feeds in our global moksha feed cache..
- :Warning: the MokshaHub will not use this unless both it and the
- Moksha WSGI app are using the same `feed_cache` database.
+ feeds = set()
+ for feed in feed_storage.keys():
+ feeds.add(str(feed))
- - Keep feed caches fresh.
+ # Read in all feeds from the `feeds.txt` file for testing...
+ if os.path.isfile('feeds.txt'):
+ feed_list = file('feeds.txt')
+ for feed in feed_list.readlines():
+ feeds.add(str(feed.strip()))
- - Send messages to topics for new entries
- `feed.$NAME` topic ?
- `tag.category
- """
- # @@ Only run once... for testing purposes
- if self.running:
- print "Feed streamer already running"
- return
- self.running = True
-
- log.debug('FeedStream.poll()')
- feeds = map(lambda x: x.strip(), file('feeds.txt').readlines())
- feeds = [(feed, '') for feed in feeds]
f = FeederFactory()
f.start(addresses=feeds)
- return
def stop(self):
feed_storage.close()
commit 452d59484e33527480838d89024c5440f850ea76
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:10:36 2009 -0500
Have our LiveFeedWidget automatically subscribe to the `feed.$URL` topic.
diff --git a/moksha/api/widgets/feed/live.py b/moksha/api/widgets/feed/live.py
index 4ceda47..3b869fb 100644
--- a/moksha/api/widgets/feed/live.py
+++ b/moksha/api/widgets/feed/live.py
@@ -38,3 +38,9 @@ class LiveFeedWidget(LiveWidget):
});
"""
feed = Feed()
+ topic = None
+
+ def update_params(self, d):
+ super(LiveFeedWidget, self).update_params(d)
+ if not d.topic:
+ d.topic = 'feed.%s' % d.url
commit ecfe0d30615b955c96e110669b475815359f0b28
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:09:50 2009 -0500
Make our Feed widget handle dicts as feed data
diff --git a/moksha/api/widgets/feed/feed.py b/moksha/api/widgets/feed/feed.py
index 3818bc1..104f564 100644
--- a/moksha/api/widgets/feed/feed.py
+++ b/moksha/api/widgets/feed/feed.py
@@ -74,9 +74,9 @@ class Feed(Widget):
feed_storage = Shove('sqlite:///feeds.db', compress=True)
feed_cache = Cache(feed_storage)
feed = feed_cache.fetch(url)
- if not (200 <= feed.status < 400):
+ if not (200 <= feed.get('status', 200) < 400):
log.warning('Got %s status from %s: %s' % (
- feed.status, url, feed.headers.get('status')))
+ feed['status'], url, feed.headers.get('status')))
d['title'] = feed.headers.get('status')
d['link'] = feed.feed.get('link')
return
@@ -87,7 +87,7 @@ class Feed(Widget):
except AttributeError:
d['title'] = 'Unable to parse feed'
return
- for i, entry in enumerate(feed.entries):
+ for i, entry in enumerate(feed.get('entries', [])):
entry['uid'] = '%s_%d' % (self.id, i)
entry['link'] = entry.get('link')
yield entry
commit 0f0da20d8bf270d9c9f329b4ed0bbba22de2d109
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 22:09:33 2009 -0500
Make our PollingDataStreamers start up right away
diff --git a/moksha/api/streams/datastream.py b/moksha/api/streams/datastream.py
index 5b476f1..b8c4756 100644
--- a/moksha/api/streams/datastream.py
+++ b/moksha/api/streams/datastream.py
@@ -31,7 +31,7 @@ class PollingDataStream(DataStream):
"""
frequency = None # Either a timedelta object, or the number of seconds
- def __init__(self):
+ def __init__(self, now=True):
super(PollingDataStream, self).__init__()
self.timer = LoopingCall(self.poll)
if isinstance(self.frequency, timedelta):
@@ -41,7 +41,7 @@ class PollingDataStream(DataStream):
else:
seconds = self.frequency
log.debug("Setting a %s second timers" % seconds)
- self.timer.start(seconds, now=False)
+ self.timer.start(seconds, now=now)
def poll(self):
raise NotImplementedError
commit d0fc5a6acc0a81e58b324416d9eab33c4a982005
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 19:59:33 2009 -0500
Remove an unnecessary method
diff --git a/moksha/lib/cache.py b/moksha/lib/cache.py
index 64d710d..00b6c70 100644
--- a/moksha/lib/cache.py
+++ b/moksha/lib/cache.py
@@ -7,9 +7,6 @@ class Cache(object):
""" A memcached-specific caching interface """
def __init__(self, url, timeout=None, prefix=None):
- self.create_memcached_cache()
-
- def create_memcached_cache(self):
try:
import memcache
except ImportError:
commit 9f1dda5f09db2453166c0a35615815b03d7e1ef8
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 19:10:22 2009 -0500
Gracefully handle not having python-memcached installed
diff --git a/moksha/lib/cache.py b/moksha/lib/cache.py
index 20536c1..64d710d 100644
--- a/moksha/lib/cache.py
+++ b/moksha/lib/cache.py
@@ -1,10 +1,22 @@
-import memcache
+import logging
+log = logging.getLogger(__name__)
+
from moksha.exc import CacheBackendException
class Cache(object):
""" A memcached-specific caching interface """
def __init__(self, url, timeout=None, prefix=None):
+ self.create_memcached_cache()
+
+ def create_memcached_cache(self):
+ try:
+ import memcache
+ except ImportError:
+ log.warning('Cannot import the `memcache` module. Install the '
+ 'python-memcached package to enable Mokshas memcached '
+ 'integration.')
+ return
self.mc = memcache.Client([url])
self.timeout = timeout or 300
self.prefix = prefix
15 years, 4 months
3 commits - moksha/lib
by Luke Macken
moksha/lib/app_globals.py | 13 +++++++++++++
moksha/lib/helpers.py | 5 +----
2 files changed, 14 insertions(+), 4 deletions(-)
New commits:
commit ab2c41cf0d10d91a1828f1005107ab5545bf89f3
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 18:56:15 2009 -0500
Fix a typo
diff --git a/moksha/lib/app_globals.py b/moksha/lib/app_globals.py
index e630ecd..b36c74e 100644
--- a/moksha/lib/app_globals.py
+++ b/moksha/lib/app_globals.py
@@ -39,4 +39,4 @@ class Globals(object):
frame = inspect.currentframe()
caller = frame.f_back.f_back.f_globals['__name__']
print "caller = ", caller
- return object.__getattr__(self, *args, **kw)
+ return object.__getattribute__(self, *args, **kw)
commit 5cc65b253c17b7505d4a301f28dfc009b2b6b6f4
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 18:55:33 2009 -0500
Start hashing out the beginnings of moksha app namespaced Globals objects
diff --git a/moksha/lib/app_globals.py b/moksha/lib/app_globals.py
index 230c024..e630ecd 100644
--- a/moksha/lib/app_globals.py
+++ b/moksha/lib/app_globals.py
@@ -1,6 +1,7 @@
"""The application's Globals object"""
import logging
+import inspect
from tg import config
from shove import Shove
@@ -27,3 +28,15 @@ class Globals(object):
except CacheBackendException, e:
log.warning(str(e))
self.cache = None
+
+ def __getattribute__(self, *args, **kw):
+ # @@ TODO: Namespace moksha app's Global objects
+ # load them in the middlware...
+ # ensure that this object is always in pylons.g, even if we are
+ # running a full moksha stack, or as middleware
+ # proxy to them on incoming request
+ print "Globals.__getattr__(%s)" % locals()
+ frame = inspect.currentframe()
+ caller = frame.f_back.f_back.f_globals['__name__']
+ print "caller = ", caller
+ return object.__getattr__(self, *args, **kw)
commit d6a0e09b934ac31cc4c7fd6806eb62958ce39a92
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 18:32:31 2009 -0500
No need to import pylons more than once in our helpers
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index 10768e4..6fa9426 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -408,15 +408,12 @@ def check_predicates(predicates):
:return: False is any one is False
:return: True if they are all True
"""
-
- from pylons import request
-
if(not(isinstance(predicates, list) or isinstance(predicates, tuple))):
predicates = (predicates,)
for p in predicates:
try:
- check_authorization(p, request.environ)
+ check_authorization(p, pylons.request.environ)
except NotAuthorizedError, e:
return False
15 years, 4 months
6 commits - docs/main moksha/exc.py moksha/lib moksha/middleware
by Luke Macken
docs/main/GettingStarted.rst | 2 -
moksha/exc.py | 3 +
moksha/lib/helpers.py | 63 +++++++++++++++++++++++++++++++---------
moksha/middleware/middleware.py | 24 +++++++--------
4 files changed, 66 insertions(+), 26 deletions(-)
New commits:
commit 37608c9f46d03284bdf8e57a15ef1852872e4cd9
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 18:29:54 2009 -0500
MokshaMiddleware.load_configs improvements and refactoring.
- Ensure we do not try and load the same configuration twice
- Ensure we load Moksha's configuration
- Ensure we can handle Moksha's configuration living in various
locations.
diff --git a/moksha/middleware/middleware.py b/moksha/middleware/middleware.py
index 4c3ccc9..ea60286 100644
--- a/moksha/middleware/middleware.py
+++ b/moksha/middleware/middleware.py
@@ -35,7 +35,8 @@ from sqlalchemy import create_engine
from feedcache.cache import Cache
from moksha.exc import ApplicationNotFound, MokshaException
-from moksha.lib.helpers import defaultdict
+from moksha.lib.helpers import (defaultdict, get_moksha_config_path,
+ get_main_app_config_path)
from moksha.wsgiapp import MokshaAppDispatcher
log = logging.getLogger(__name__)
@@ -270,12 +271,18 @@ class MokshaMiddleware(object):
where it is being run as WSGI middleware in a different environment.
"""
- moksha_conf = os.path.abspath(__file__ + '/../../../')
- for app in [{'path': moksha_conf}] + moksha.apps.values():
+ config_paths = set()
+ moksha_config_path = os.path.dirname(get_moksha_config_path())
+ main_app_config_path = os.path.dirname(get_main_app_config_path())
+ for app in [{'path': moksha_config_path}] + moksha.apps.values():
+ if app['path'] != main_app_config_path and \
+ app['path'] not in config_paths:
+ config_paths.add(app['path'])
+ for config_path in config_paths:
for configfile in ('production.ini', 'development.ini'):
- confpath = os.path.join(app['path'], configfile)
+ confpath = os.path.join(config_path, configfile)
if os.path.exists(confpath):
- log.debug('Loading configuration: %s' % confpath)
+ log.info('Loading configuration: %s' % confpath)
conf = appconfig('config:' + confpath)
for entry in conf.global_conf:
if entry.startswith('_'):
commit 278e4d4f693633ffb2c557f20c6ef938c185072e
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 18:29:22 2009 -0500
Add get_moksha_config_path and get_main_app_config_path methods to our helpers
diff --git a/moksha/exc.py b/moksha/exc.py
index 442f131..ee5f3eb 100644
--- a/moksha/exc.py
+++ b/moksha/exc.py
@@ -28,3 +28,6 @@ class WidgetNotFound(MokshaException):
class CacheBackendException(MokshaException):
pass
+
+class MokshaConfigNotFound(MokshaException):
+ pass
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index 8d19fcb..10768e4 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -3,21 +3,21 @@ import pylons
import uuid
import simplejson as json
import re
-
-from webhelpers import date, feedgenerator, html, number, misc, text
-
-from repoze.what.predicates import (Not, Predicate, All, Any, has_all_permissions,
- has_any_permission, has_permission,
- in_all_groups, in_any_group, in_group,
- is_user, not_anonymous)
-
-from repoze.what.authorize import check_authorization, NotAuthorizedError
+import os
+import logging
from webob import Request
-
from decorator import decorator
+from webhelpers import date, feedgenerator, html, number, misc, text
+from repoze.what.authorize import check_authorization, NotAuthorizedError
+from repoze.what.predicates import (Not, Predicate, All, Any,
+ has_all_permissions, has_any_permission,
+ has_permission, in_all_groups, in_any_group,
+ in_group, is_user, not_anonymous)
+from moksha.exc import MokshaConfigNotFound
+log = logging.getLogger(__name__)
scrub_filter = re.compile('[^_a-zA-Z0-9-]')
def _update_params(params, d):
@@ -516,13 +516,39 @@ def cache_rendered(func, *args, **kwargs):
def in_full_moksha_stack():
- """ Figure out if we are running Moksha as WSGI middleware, or in our full stack.
-
- :returns True: If we are currently running in Moksha's full WSGI stack
- :returns False: If are are only running Moksha as WSGI middleware
+ """
+ Figure out if we are running Moksha as WSGI middleware, or in our full stack.
+ :returns: True if we are currently running in Moksha's full WSGI stack,
+ False if we are running Moksha only as WSGI middleware.
"""
try:
- from pylons import config
- return config.get('app_conf', {}).get('package', 'notmoksha') == 'moksha'
+ return pylons.config['app_conf']['package'] == 'moksha'
except:
return False
+
+
+def get_main_app_config_path():
+ """
+ :returns: The path to the main applications configuratoin file
+ """
+ try:
+ return pylons.config['__file__']
+ except:
+ log.error('Cannot find main applications config file in '
+ 'pylons.config["__file__"]')
+
+
+def get_moksha_config_path():
+ """
+ :returns: The path to Moksha's configuration file.
+ """
+ if in_full_moksha_stack():
+ return get_main_app_config_path()
+ else:
+ for config_file in ('production.ini', 'development.ini'):
+ for config_path in ('/etc/moksha/', __file__ + '/../../../'):
+ cfg = os.path.join(os.path.abspath(config_path), config_file)
+ if os.path.isfile(cfg):
+ return cfg
+
+ raise MokshaConfigNotFound('Cannot find moksha configuration file!')
commit 941844a524c82710c69795b53a660fd287d59efd
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 17:43:10 2009 -0500
Add a moksha.lib.helpers.is_full_moksha_stack() method to figure out if we
are running as middleware, or using the full Moksha stack.
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index fed408b..8d19fcb 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -513,3 +513,16 @@ def cache_rendered(func, *args, **kwargs):
content = func(*args, **kwargs)
cache_rendered_data(content)
return content
+
+
+def in_full_moksha_stack():
+ """ Figure out if we are running Moksha as WSGI middleware, or in our full stack.
+
+ :returns True: If we are currently running in Moksha's full WSGI stack
+ :returns False: If are are only running Moksha as WSGI middleware
+ """
+ try:
+ from pylons import config
+ return config.get('app_conf', {}).get('package', 'notmoksha') == 'moksha'
+ except:
+ return False
commit c40d000eb5f180cce58b6da540b1cf23e276f8ea
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 17:42:53 2009 -0500
Clean up our clean_rendered decorator
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index 4dd070d..fed408b 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -511,7 +511,5 @@ def cache_rendered_data(data):
@decorator
def cache_rendered(func, *args, **kwargs):
content = func(*args, **kwargs)
- if pylons.g.cache and \
- pylons.request.environ.get('HTTP_X_FORWARDED_PROTO'):
- pylons.g.cache.set(pylons.request.path_qs, str(content))
+ cache_rendered_data(content)
return content
commit ac96b1df5f7fc982fb562712d73f907a7a8a6858
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 17:41:37 2009 -0500
Add a few more deps to our initial dependency tree
diff --git a/docs/main/GettingStarted.rst b/docs/main/GettingStarted.rst
index 3a7371b..f865d07 100644
--- a/docs/main/GettingStarted.rst
+++ b/docs/main/GettingStarted.rst
@@ -24,7 +24,7 @@ You'll need the `virtualenv <http://pypi.python.org/pypi/virtualenv>`_ package.
.. code-block:: bash
- # yum -y install python-virtualenv pysvn mercurial
+ # yum -y install python-virtualenv pysvn mercurial PyOpenSSL python-memcached
The `start-moksha` script mentioned below should install all of the necessary
dependencies. However, it will attempt to compile a few things, such as lxml. So, you may need to install some additional dependencies like `libxml2` and `libxslt` in order to build it. If you're using yum, you can easily install all of the build requirements by doing:
commit 308204e683d120f5e711c2dd22c0d690b5bbf875
Author: Luke Macken <lmacken(a)redhat.com>
Date: Tue Feb 17 15:59:54 2009 -0500
No need to load the model for WSGI mounted apps
diff --git a/moksha/middleware/middleware.py b/moksha/middleware/middleware.py
index 156a7ba..4c3ccc9 100644
--- a/moksha/middleware/middleware.py
+++ b/moksha/middleware/middleware.py
@@ -149,13 +149,6 @@ class MokshaMiddleware(object):
'path': app_path,
'model': None,
}
- try:
- model = __import__('%s.model' % app_entry.name,
- globals(), locals(),
- [app_entry.name])
- moksha.apps[app_entry.name]['model'] = model
- except ImportError:
- pass
def load_widgets(self):
log.info('Loading moksha widgets')
15 years, 4 months