moksha/api moksha/middleware moksha/public
by John (J5) Palmieri
moksha/api/widgets/containers/templates/layout_applist.mak | 2
moksha/middleware/csrfmiddleware.py | 132 +++++++++++++
moksha/public/javascript/moksha.js | 2
3 files changed, 134 insertions(+), 2 deletions(-)
New commits:
commit 1ea5af5b15c0b2d6b763d5afe0a93d1f03a64111
Author: John (J5) Palmieri <johnp(a)redhat.com>
Date: Thu Feb 26 17:05:33 2009 -0500
add new csrf middleware and fix the csrf_rewrite_url function
* we now have a middleware that strips the csrf tokens from the query parameters
and puts them in environ and a metadata plugin which strips the identity
and credentials if the csrf check fails. To use this feature you need
to override add_auth_middleware in your AppConfig. Here is a sample for
the fas auth plugins:
def fas_make_who_middleware(app, log_stream):
# This is both the middleware and the metadata plugin
csrf_app = CSRFProtectionMiddleware()
faswho = FASWhoPlugin(fasurl)
form = RedirectingFormPlugin('/login', '/login_handler',
'/logout', rememberer_name='fasident')
form.classifications = { IIdentifier:['browser'],
IChallenger:['browser'] } # only for browser
identifiers = [('form', form),('fasident', faswho)]
authenticators = [('fasauth', faswho)]
challengers = [('form',form)]
# add csrf as a metadata plugin
mdproviders = [('fasmd', faswho), ('csrfmd', csrf_app)]
if os.environ.get('FAS_WHO_LOG'):
log_stream = sys.stdout
# create the auth middleware as usual
middleware = PluggableAuthenticationMiddleware(
app,
identifiers,
authenticators,
challengers,
mdproviders,
default_request_classifier,
default_challenge_decider,
log_stream = log_stream
)
# but instead of returning it register it with the csrf app
csrf_app.register_application(middleware)
# return the csrf app
return csrf_app
* the csrf_rewrite_url function was double writting the token when we
moved to modifying the query hash instead of just concatinating. While
we moved to modifying the query hash we also forgot to remove the code that
concatinated the value to the query string
diff --git a/moksha/api/widgets/containers/templates/layout_applist.mak b/moksha/api/widgets/containers/templates/layout_applist.mak
index b2e21bc..24be703 100644
--- a/moksha/api/widgets/containers/templates/layout_applist.mak
+++ b/moksha/api/widgets/containers/templates/layout_applist.mak
@@ -25,7 +25,7 @@
data: ${app['params']}
};
- $.ajax(ajaxOptions);
+ $(document).ready(function () {$.ajax(ajaxOptions)});
</script>
% endif
diff --git a/moksha/middleware/csrfmiddleware.py b/moksha/middleware/csrfmiddleware.py
new file mode 100644
index 0000000..33e5132
--- /dev/null
+++ b/moksha/middleware/csrfmiddleware.py
@@ -0,0 +1,132 @@
+# This file is part of Moksha.
+#
+# Moksha is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Moksha is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Moksha. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2008, Red Hat, Inc.
+# Authors: John (J5) Palmieri <johnp(a)redhat.com>
+
+import logging
+
+from webob import Request, Response
+from hashlib import sha1
+
+from paste.request import construct_url
+from paste.httpexceptions import HTTPFound
+from paste.request import parse_formvars, parse_dict_querystring
+from paste.response import replace_header
+
+from urlparse import urlparse, urlunparse
+
+log = logging.getLogger(__name__)
+
+class CSRFProtectionMiddleware(object):
+ """
+ A layer of WSGI middleware that is responsible for making sure authenticated
+ requests originated from the user inside of the app's domain
+ and not a malicious website
+
+ This middleware works with Repoze.who and Repoze.what auth middleware
+ and must be run right before the who middleware and as a metadata plugin
+ for repoze.who. If the user is authenticated
+ and the csrf token is not the sha1 hash of the session id or
+ environ['CSRF_AUTH_SESSION_ID'] we clear environ['repoze.who.identity'] and
+ environ['repoze.what.credentials']
+
+ If the check succeeds we add the sha1 hash to the identity hash as
+ {self.csrf_token: sessionid_sha1_hash}
+ """
+
+ _connectors = {}
+
+ def __init__(self,
+ session_cookie='tg-visit',
+ session_env='CSRF_AUTH_SESSION_ID',
+ token_env='CSRF_TOKEN',
+ csrf_token_id = '_csrf_token',
+ clear_env = ['repoze.who.identity', 'repoze.what.credentials']):
+ log.info('Creating CSRFProtectionMiddleware')
+ self.application = None
+ self.session_cookie = session_cookie
+ self.session_env = session_env
+ self.csrf_token_id = csrf_token_id
+ self.clear_env = clear_env
+ self.token_env = token_env
+
+ def register_application(self, app):
+ self.application = app
+
+ def __call__(self, environ, start_response):
+ """ Clear out the csrf token and place it in the environ
+
+ This middleware must be placed before the repoze.who middleware
+ """
+ request = Request(environ)
+
+ csrf_token = None
+ d = parse_dict_querystring(environ)
+ if self.csrf_token_id in d:
+ csrf_token= d.getone(self.csrf_token_id)
+ d.__delitem__(self.csrf_token_id)
+
+ qs = []
+ for k in d:
+ qs.append('%s=%s'%(k,d[k]))
+
+ qs = '&'.join(qs)
+ environ['QUERY_STRING'] = qs
+
+ d = parse_formvars(environ, False)
+ if self.csrf_token_id in d:
+ csrf_token = d.getone(self.csrf_token_id)
+ d.__delitem__(self.csrf_token_id)
+ environ['paste.parsed_formvars'] = d
+
+ environ[self.token_env] = csrf_token
+
+ response = request.get_response(self.application)
+ return response(environ, start_response)
+
+ def add_metadata(self, environ, identity):
+ """
+ Repoze.who metadata pluging. This must be placed as the last
+ metadata plugin to run. It clears the identity and credentials
+ if the csrf check fails. The Repoze.who Auth plugin must also
+ set CSRF_AUTH_SESSION_ID in the environ so we don't clear
+ in the initial authorization stage
+ """
+ request = Request(environ)
+
+ session_id = environ.get(self.session_env, None)
+ auth_state = True
+ if not session_id:
+ auth_state = False
+ session_id = request.cookies.get(self.session_cookie)
+
+ token = None
+ if session_id:
+ token = sha1(session_id)
+ token = token.hexdigest()
+ info = {self.csrf_token_id: token}
+ identity.update(info)
+
+ # check for csrf
+ if (auth_state):
+ app = environ['repoze.who.application']
+ p = list(urlparse(app.location()))
+ p[4] += '&' + self.csrf_token_id + '=' + token
+ replace_header(app.headers, 'location', urlunparse(tuple(p)))
+ elif not token or token != environ.get(self.token_env):
+ for k in self.clear_env:
+ if k in environ:
+ del environ[k]
diff --git a/moksha/public/javascript/moksha.js b/moksha/public/javascript/moksha.js
index 662c4e3..d5ae03f 100644
--- a/moksha/public/javascript/moksha.js
+++ b/moksha/public/javascript/moksha.js
@@ -109,7 +109,7 @@ moksha = {
}
var query = qlist.join('&')
- newurl += '?'+ query + moksha_csrf_token;
+ newurl += '?'+ query;
if (ourl.anchor)
newurl += '#' + ourl.anchor;
15 years, 3 months
moksha/api moksha/middleware moksha/public
by John (J5) Palmieri
moksha/api/connectors.py | 1 +
moksha/middleware/connector.py | 15 +++++++++++----
moksha/public/javascript/moksha.js | 13 +++++++++++--
3 files changed, 23 insertions(+), 6 deletions(-)
New commits:
commit 48c5882558db551fea6694ad1a09be206dcd4ac5
Author: John (J5) Palmieri <johnp(a)redhat.com>
Date: Mon Feb 23 19:53:05 2009 -0500
fix up the connectors a bit and fix csrf url rewritting
diff --git a/moksha/api/connectors.py b/moksha/api/connectors.py
new file mode 100644
index 0000000..d07b7b6
--- /dev/null
+++ b/moksha/api/connectors.py
@@ -0,0 +1 @@
+from moksha.middleware.connector import _get_connector as get_connector
\ No newline at end of file
diff --git a/moksha/middleware/connector.py b/moksha/middleware/connector.py
index f1f0291..9193058 100644
--- a/moksha/middleware/connector.py
+++ b/moksha/middleware/connector.py
@@ -38,11 +38,12 @@ class MokshaConnectorMiddleware(object):
run that connector as defined in it's egg-info.
"""
+
+ _connectors = {}
+
def __init__(self, application):
log.info('Creating MokshaConnectorMiddleware')
self.application = application
- self.connectors = {} # {'connector name': moksha.IConnector class}
-
self.load_connectors()
def __call__(self, environ, start_response):
@@ -89,7 +90,7 @@ class MokshaConnectorMiddleware(object):
path = path[:-1]
path = '/'.join(path)
- conn = self.connectors.get(conn)
+ conn = self._connectors.get(conn)
if conn:
conn_obj = conn['connector_class']()
@@ -111,8 +112,14 @@ class MokshaConnectorMiddleware(object):
# FIXME: Should we pass some resource in?
conn_class.register()
conn_path = conn_entry.dist.location
- self.connectors[conn_entry.name] = {
+ self._connectors[conn_entry.name] = {
'name': conn_entry.name,
'connector_class': conn_class,
'path': conn_path,
}
+
+def _get_connector(name):
+ # TODO: having a connection pool might be nice
+ c = MokshaConnectorMiddleware._connectors[name]
+
+ return c['connector_class']()
\ No newline at end of file
diff --git a/moksha/public/javascript/moksha.js b/moksha/public/javascript/moksha.js
index ba98362..662c4e3 100644
--- a/moksha/public/javascript/moksha.js
+++ b/moksha/public/javascript/moksha.js
@@ -102,8 +102,17 @@ moksha = {
if (proto)
proto += '://';
var newurl = proto + ourl.authority + ourl.path;
- newurl += '?' + ourl.query + '&_csrf_token=' + moksha_csrf_token;
- newurl += '#' + ourl.anchor;
+ var qlist = []
+ ourl.queryKey['_csrf_token'] = moksha_csrf_token;
+ for (q in ourl.queryKey) {
+ qlist.push(q + '=' + ourl.queryKey[q]);
+ }
+
+ var query = qlist.join('&')
+ newurl += '?'+ query + moksha_csrf_token;
+
+ if (ourl.anchor)
+ newurl += '#' + ourl.anchor;
return newurl;
15 years, 4 months
moksha/lib
by Luke Macken
moksha/lib/helpers.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
New commits:
commit 950e9851a05a1ac51a70512e0a31c539761ece21
Author: Luke Macken <lmacken(a)redhat.com>
Date: Thu Feb 19 14:57:08 2009 -0500
Fix our get_main_app_config_path() method
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index 96093c0..e8c4ca0 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -9,6 +9,7 @@ from repoze.what.authorize import check_authorization, NotAuthorizedError
from webob import Request
+import pylons
import urllib
import uuid
import simplejson as json
@@ -535,7 +536,7 @@ def get_main_app_config_path():
"""
try:
return pylons.config['__file__']
- except:
+ except KeyError:
log.error('Cannot find main applications config file in '
'pylons.config["__file__"]')
15 years, 4 months
moksha/api moksha/public setup.py
by John (J5) Palmieri
moksha/api/widgets/containers/templates/layout_applist.mak | 2
moksha/api/widgets/moksha.py | 29 ++++++
moksha/public/javascript/moksha.js | 55 ++++++++++++-
moksha/public/javascript/ui/moksha.ui.tabs.js | 2
setup.py | 2
5 files changed, 86 insertions(+), 4 deletions(-)
New commits:
commit ba83263a508529c2127b6434e903f95f55452510
Author: John (J5) Palmieri <johnp(a)redhat.com>
Date: Wed Feb 18 22:35:41 2009 -0500
make csrf work - all that is left is link rewritting
diff --git a/moksha/api/widgets/containers/templates/layout_applist.mak b/moksha/api/widgets/containers/templates/layout_applist.mak
index bf267c4..b2e21bc 100644
--- a/moksha/api/widgets/containers/templates/layout_applist.mak
+++ b/moksha/api/widgets/containers/templates/layout_applist.mak
@@ -15,7 +15,7 @@
<script type="text/javascript">
<!-- TODO: make this a JS widget -->
var ajaxOptions = {
- url: "${app['url']}",
+ url: moksha.csrf_rewrite_url("${app['url']}"),
success: function(r, s) {
var $panel = $("#${app['id']}");
var $stripped = moksha.filter_resources(r);
diff --git a/moksha/api/widgets/moksha.py b/moksha/api/widgets/moksha.py
index baff13e..c063860 100644
--- a/moksha/api/widgets/moksha.py
+++ b/moksha/api/widgets/moksha.py
@@ -17,5 +17,34 @@
# Authors: John (J5) Palmieri <johnp(a)redhat.com>
from tw.jquery import jquery_js
from tw.api import JSLink
+from tw.api import Widget
+import tg
+import pylons
+
moksha_js = JSLink(modname="moksha", filename='public/javascript/moksha.js',
javascript=[jquery_js])
+
+class MokshaGlobals(Widget):
+ javascript = [moksha_js]
+ template = """<script type="text/javascript">
+moksha_base_url = "${base_url}";
+moksha_csrf_token = "${csrf_token}";
+moksha_userid = "${user_id}";
+</script>
+"""
+ params = ['base_url', 'csrf_token', 'user_id']
+ engine_name = 'mako'
+
+ base_url = '/'
+ csrf_token = ''
+ user_id = ''
+
+ def update_params(self, d):
+ super(MokshaGlobals, self).update_params(d)
+ d['base_url'] = tg.url('/')
+ identity = pylons.request.environ.get('repoze.who.identity')
+
+ if identity:
+ d['csrf_token'] = identity.get('_csrf_token','')
+ d['user_id'] = identity.get('user_id', '')
+
diff --git a/moksha/public/javascript/moksha.js b/moksha/public/javascript/moksha.js
index d4a977b..ba98362 100644
--- a/moksha/public/javascript/moksha.js
+++ b/moksha/public/javascript/moksha.js
@@ -87,7 +87,60 @@ moksha = {
var $f = moksha.filter_scripts(fragment);
return $f;
- }
+ },
+
+ /********************************************************************
+ * Take a url and attach the csrf hash if available
+ ********************************************************************/
+ csrf_rewrite_url: function(url) {
+ if (typeof(moksha_csrf_token) === 'undefined' || !moksha_csrf_token)
+ return url;
+
+ var ourl = moksha.parseUri(url);
+
+ var proto = ourl.protocol;
+ if (proto)
+ proto += '://';
+ var newurl = proto + ourl.authority + ourl.path;
+ newurl += '?' + ourl.query + '&_csrf_token=' + moksha_csrf_token;
+ newurl += '#' + ourl.anchor;
+
+ return newurl;
+
+ },
+
+ /*
+ * modified from parseUri 1.2.1 Steven Levithan <stevenlevithan.com>
+ */
+ parseUri: function (str) {
+ var options = {
+ strictMode: false,
+ key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
+ q: {
+ name: "queryKey",
+ parser: /(?:^|&)([^&=]*)=?([^&]*)/g
+ },
+ parser: {
+ strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
+ loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
+ }
+ };
+
+ var o = options,
+ m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
+ uri = {},
+ i = 14;
+
+ while (i--) uri[o.key[i]] = m[i] || "";
+
+ uri[o.q.name] = {};
+ uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
+ if ($1) uri[o.q.name][$1] = $2;
+ });
+
+ return uri;
+ },
+
}
})();
\ No newline at end of file
diff --git a/moksha/public/javascript/ui/moksha.ui.tabs.js b/moksha/public/javascript/ui/moksha.ui.tabs.js
index b216610..63ba21b 100644
--- a/moksha/public/javascript/ui/moksha.ui.tabs.js
+++ b/moksha/public/javascript/ui/moksha.ui.tabs.js
@@ -529,7 +529,7 @@ $.widget("ui.mokshatabs", {
url += self.path_remainder;
var ajaxOptions = $.extend({}, o.ajaxOptions, {
- url: url,
+ url: moksha.csrf_rewrite_url(url),
success: function(r, s) {
var $panel = $(a.hash + ':first', self.element);
var $stripped = moksha.filter_resources(r);
diff --git a/setup.py b/setup.py
index d930a38..9cdee61 100644
--- a/setup.py
+++ b/setup.py
@@ -79,7 +79,7 @@ setup(
orbited = moksha.api.widgets.orbited:orbited_js
jquery = tw.jquery:jquery_js
- moksha = moksha.api.widgets.moksha:moksha_js
+ moksha = moksha.api.widgets.moksha:MokshaGlobals
jquery_ui_core = tw.jquery.ui:ui_core_js
jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js
jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js
15 years, 4 months
moksha/api
by John (J5) Palmieri
moksha/api/widgets/containers/dashboardcontainer.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 4a60e4a07b42c50189096ec41ad9cd74316c9e58
Author: John (J5) Palmieri <johnp(a)redhat.com>
Date: Wed Feb 18 18:20:12 2009 -0500
fix merge typo
diff --git a/moksha/api/widgets/containers/dashboardcontainer.py b/moksha/api/widgets/containers/dashboardcontainer.py
index 6b34e2a..ad98cc5 100644
--- a/moksha/api/widgets/containers/dashboardcontainer.py
+++ b/moksha/api/widgets/containers/dashboardcontainer.py
@@ -1,7 +1,7 @@
from moksha.api.widgets.layout.layout import layout_js, layout_css, ui_core_js, ui_draggable_js, ui_droppable_js, ui_sortable_js
from tw.api import Widget
-from twfrom.jquery import jquery_js
+from tw.jquery import jquery_js
from moksha.lib.helpers import eval_app_config, ConfigWrapper
from tg import config
from tw.api import Widget
15 years, 4 months
moksha/api moksha/lib moksha/public setup.py
by John (J5) Palmieri
moksha/api/widgets/containers/dashboardcontainer.py | 7
moksha/api/widgets/containers/templates/layout_applist.mak | 19 -
moksha/api/widgets/grid.py | 11
moksha/api/widgets/moksha.py | 21 +
moksha/lib/base.py | 12 -
moksha/lib/helpers.py | 27 +-
moksha/public/javascript/moksha.js | 85 +++++++
moksha/public/javascript/ui/moksha.ui.grid.js | 148 ++++++-------
moksha/public/javascript/ui/moksha.ui.tabs.js | 10
setup.py | 11
10 files changed, 221 insertions(+), 130 deletions(-)
New commits:
commit fd6e566f9a8362ec4e7a61ac954ee1daab1841b3
Author: John (J5) Palmieri <johnp(a)redhat.com>
Date: Wed Feb 18 18:09:11 2009 -0500
fix up script filtering and use uuid's for the grid
diff --git a/moksha/api/widgets/containers/dashboardcontainer.py b/moksha/api/widgets/containers/dashboardcontainer.py
index bb1335b..6b34e2a 100644
--- a/moksha/api/widgets/containers/dashboardcontainer.py
+++ b/moksha/api/widgets/containers/dashboardcontainer.py
@@ -1,3 +1,8 @@
+from moksha.api.widgets.layout.layout import layout_js, layout_css, ui_core_js, ui_draggable_js, ui_droppable_js, ui_sortable_js
+
+from tw.api import Widget
+from twfrom.jquery import jquery_js
+from moksha.lib.helpers import eval_app_config, ConfigWrapper
from tg import config
from tw.api import Widget
@@ -22,6 +27,8 @@ applist_widget = AppListWidget('applist');
class DashboardContainer(Widget):
template = 'mako:moksha.api.widgets.containers.templates.dashboardcontainer'
+ css = []
+ javascript = [jquery_js]
config_key = None
layout = []
diff --git a/moksha/api/widgets/containers/templates/layout_applist.mak b/moksha/api/widgets/containers/templates/layout_applist.mak
index d9d8a24..bf267c4 100644
--- a/moksha/api/widgets/containers/templates/layout_applist.mak
+++ b/moksha/api/widgets/containers/templates/layout_applist.mak
@@ -5,21 +5,6 @@
<dt>${app['label']}</dt>
% endif
- <script type="text/javascript">
- function moksha_strip_and_display(r, panel) {
- var $temp = $(r);
- var $scripts = $temp.find("script[src]");
- $scripts.remove();
-
- var $stripped = [];
- $.each($temp, function(i, s) {
- if (!$(s).is('script[src]')){
- $stripped.push(s);
- }
- });
- panel.html($stripped);
- }
- </script>
<dd id="${app['id']}">
% if app.has_key('widget'):
${app['widget'](**app['params'])}
@@ -33,7 +18,9 @@
url: "${app['url']}",
success: function(r, s) {
var $panel = $("#${app['id']}");
- moksha_strip_and_display(r, $panel);
+ var $stripped = moksha.filter_resources(r);
+ $panel.html($stripped);
+
},
data: ${app['params']}
};
diff --git a/moksha/api/widgets/grid.py b/moksha/api/widgets/grid.py
index 7469c3a..cec51aa 100644
--- a/moksha/api/widgets/grid.py
+++ b/moksha/api/widgets/grid.py
@@ -3,6 +3,8 @@ from tw.forms import FormField
from tw.jquery.ui_core import jquery_ui_core_js
from tw.jquery import jQuery, jquery_js
import simplejson as json
+import uuid
+
jquery_json_js = JSLink(filename='public/javascript/jquery.json.js',
modname='moksha', javascript=[jquery_js])
@@ -19,7 +21,7 @@ class Grid(FormField):
params= ['rows_per_page', 'page_num', 'total_rows',
'filters', 'unique_key', 'sort_key', 'sort_order',
'row_template', 'resource', 'resource_path',
- 'loading_throbber']
+ 'loading_throbber', 'uid']
rows_per_page = 10
page_num = 1
@@ -47,7 +49,6 @@ class Grid(FormField):
grid_d[p] = v
- id = d['id']
- if d.get('uid'):
- id += d.uid
- self.add_call(jQuery("#%s" % id).mokshagrid(grid_d))
+ d['id'] += "-uuid" + str(uuid.uuid4())
+
+ self.add_call(jQuery("#%s" % d['id']).mokshagrid(grid_d))
diff --git a/moksha/api/widgets/moksha.py b/moksha/api/widgets/moksha.py
new file mode 100644
index 0000000..baff13e
--- /dev/null
+++ b/moksha/api/widgets/moksha.py
@@ -0,0 +1,21 @@
+# This file is part of Moksha.
+#
+# Moksha is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Moksha is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Moksha. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2008, Red Hat, Inc.
+# Authors: John (J5) Palmieri <johnp(a)redhat.com>
+from tw.jquery import jquery_js
+from tw.api import JSLink
+moksha_js = JSLink(modname="moksha", filename='public/javascript/moksha.js',
+ javascript=[jquery_js])
diff --git a/moksha/lib/base.py b/moksha/lib/base.py
index 7d77a1b..16cd23e 100644
--- a/moksha/lib/base.py
+++ b/moksha/lib/base.py
@@ -43,19 +43,13 @@ class BaseController(TGController):
# url is already taken
tmpl_context.get_url = url
- ## Inject our global resources
- if request.path.startswith('/appz') or \
- request.path.startswith('/widgets') or \
- request.path.startswith('/docs'):
- # Don't inject global resources for apps or widgets.
- tmpl_context.moksha_global_resources = lambda: ''
- else:
+
# Add our global widget to the template context, and register it's resources
- tmpl_context.moksha_global_resources = global_resources
+ tmpl_context.moksha_global_resources = global_resources
# This is normally done when the widget is rendered, but we cannot assume that
# moksha apps are going to be using our master index template, which renders
# this widget for us.
- global_resources.register_resources()
+ global_resources.register_resources()
return TGController.__call__(self, environ, start_response)
diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py
index 6fa9426..96093c0 100644
--- a/moksha/lib/helpers.py
+++ b/moksha/lib/helpers.py
@@ -1,5 +1,15 @@
-import moksha
-import pylons
+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
+
+from webob import Request
+
+import urllib
import uuid
import simplejson as json
import re
@@ -8,14 +18,7 @@ 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
+import moksha
log = logging.getLogger(__name__)
scrub_filter = re.compile('[^_a-zA-Z0-9-]')
@@ -408,12 +411,14 @@ 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, pylons.request.environ)
+ check_authorization(p, request.environ)
except NotAuthorizedError, e:
return False
diff --git a/moksha/public/javascript/moksha.js b/moksha/public/javascript/moksha.js
index 9c5641f..d4a977b 100644
--- a/moksha/public/javascript/moksha.js
+++ b/moksha/public/javascript/moksha.js
@@ -1,7 +1,7 @@
/*
* Moksha javascript library
*
- * Copyright (c) 2008 Red Hat, Inc.
+ * Copyright (c) 2008 Red Hat, Inc.
*
* GPLv2+ license.
*
@@ -9,4 +9,85 @@
* jquery.js
*/
-/* nothing for now */
+(function(){
+
+// prevent double loading
+if (!(typeof(moksha) === 'undefined'))
+ return;
+
+var _moksha_page_scripts_cache = {};
+
+var _moksha_init = false;
+// preload cache
+
+$(document).ready(function(){
+ _moksha_init = true;
+ var $s = $('script[src]');
+
+ $.each($s, function(i, a) {
+ var $a = $(a);
+ var src = $a.attr('src');
+ // for right now just compare exact source values
+ // later we will want to be a bit smarter
+ if(!_moksha_page_scripts_cache[src]) {
+ _moksha_page_scripts_cache[src] = true;
+ }
+ }
+ );
+
+});
+
+moksha = {
+ /******************************************************************
+ * Filter the script tags in a fragment of HTML or jQuery DOM
+ * so that they aren't double loaded. You should send in HTML
+ * if possible because placing script tags in a jQuery DOM can
+ * cause them to load if not done correctly
+ ******************************************************************/
+ filter_scripts: function(fragment) {
+ // don't append to a tag, doing so will cause scripts to load
+ if (!fragment.jquery)
+ fragment = $(fragment);
+
+ var $stripped = [];
+ $.each(fragment, function(i, s) {
+ var $s = $(s)
+ if ($s.is('script[src]')){
+ var src = $s.attr('src');
+ //strip query string
+ src = src.split('?')[0];
+
+ if(!_moksha_page_scripts_cache[src]) {
+ // we can add more attributes later
+ // right now just set to true
+ _moksha_page_scripts_cache[src] = true;
+ $stripped.push(s);
+ }
+ } else {
+ $stripped.push(s);
+ }
+ });
+
+ return $stripped;
+ },
+
+ /******************************************************************
+ * Filter resources in a fragment of HTML or jQuery DOM
+ * so that they aren't double loaded. Right now this is only
+ * scripts but could be expanded to css and other loaded
+ * resource types. You should send in HTML
+ * if possible since loading into a jQuery DOM can cause them
+ * to load if not done correctly
+ ******************************************************************/
+ filter_resources: function(fragment) {
+ if (!fragment.jquery)
+ fragment = $(fragment);
+
+ var $div = $('<div />');
+ var $f = moksha.filter_scripts(fragment);
+
+ return $f;
+ }
+}
+
+})();
\ No newline at end of file
diff --git a/moksha/public/javascript/ui/moksha.ui.grid.js b/moksha/public/javascript/ui/moksha.ui.grid.js
index 4f64b74..f6b60eb 100644
--- a/moksha/public/javascript/ui/moksha.ui.grid.js
+++ b/moksha/public/javascript/ui/moksha.ui.grid.js
@@ -1,107 +1,107 @@
(function($) {
- $.widget("ui.mokshagrid",{
+ $.widget("ui.mokshagrid",{
/* methods */
-
+
init: function() {
var self = this;
var o = self.options;
-
+
self.$visible_rows = [];
// add placeholder for row appends
self.$rowplaceholder = jQuery('<span />').addClass('moksha_rowplaceholder');
self.$rowplaceholder.hide();
-
-
- if (!self.element.is('table')) {
+
+
+ if (!self.element.is('table')) {
var t = self._generate_table();
-
+
self.element.append(t);
} else {
self._setup_template();
- }
+ }
},
-
+
destroy: function() {
this.$headers.unbind('.mokshagrid');
this.element.unbind('.mokshagrid');
},
-
+
clear: function() {
var self = this;
var rows = self.$visible_rows;
for (i in rows)
rows[i].replaceWith('');
-
+
self.$visible_rows = [];
},
-
+
insert_row: function(i, row_data) {
var self = this;
var o = self.options
var rows = self.$visible_rows;
var row_count = self.visible_row_count();
-
+
// store the widget for this element
jQuery.data(self.element, 'mokshagrid', self);
-
+
// do nothing if we are asked to insert passed
// the number of rows being displayed
if (i >= o.rows_per_page || (i == -1 && row_count >= o.rows_per_page))
return;
-
+
var new_row = jQuery(o.row_template.apply(row_data));
-
+
if (i == -1 || row_count == i) {
// append to the end of the tracking array and the table dom
rows.push(new_row);
self.$rowplaceholder.before(new_row);
} else {
-
+
// insert before i element in the tracking array and table dom
rows[i].before(new_row);
rows.splice(i, 0, new_row);
-
+
// if there is one too many rows remove the last one
if (row_count == o.rows_per_page)
self.remove_row(o.rows_per_page);
}
-
+
new_row.show();
},
-
+
append_row: function(row_data) {
var self = this;
self.insert_row(-1, row_data);
},
-
+
remove_row: function(i) {
var self = this;
var rows = self.$visible_rows;
rows[i].replaceWith('');
rows.splice(i,1);
},
-
+
get_json: function(path, args, callback) {
- //TODO: implement a json loading method
+ //TODO: implement a json loading method
// which starts and stops a loading
// throbber
var self = this;
-
+
self.element.find('tbody').fadeOut('slow');
var xmlrequest = jQuery.getJSON(path, args, function (json) {
callback(json);
self.element.find('tbody').fadeIn('slow');
-
+
});
-
+
},
-
+
connector_query_model: function(connector, path, callback) {
path = '/moksha_connector/' + connector + '/query_model/' + path;
this.get_json(path, {}, callback);
},
-
+
connector_query: function(connector, path, dispatch_data, callback) {
path = '/moksha_connector/' + connector + '/query/' + path;
if (dispatch_data)
@@ -109,16 +109,16 @@
this.get_json(path, {}, callback);
},
-
+
request_data_refresh: function(event) {
// TODO: allow an optional rows_requested parameter
var self = this;
var o = self.options;
-
+
// figure out which row to start with
var rpp = o.rows_per_page;
var start_row = (o.page_num - 1) * rpp;
-
+
// setup the search criteria
var search_criteria = {
filters: o.filters,
@@ -127,61 +127,61 @@
sort_key: o.sort_key,
sort_order: o.sort_order,
}
-
+
// TODO: Only trigger refresh signal if we have a cache miss
self.refresh_data(event, search_criteria);
},
-
+
refresh_data: function(event, search_criteria) {
var self = this;
var o = self.options;
-
+
if (!o.resource || !o.resource_path)
return;
-
+
var results = function(json) {
self.clear();
for (var i in json.rows) {
- self.append_row(json.rows[i]);
+ self.append_row(json.rows[i]);
}
}
-
+
var filters = search_criteria.filters
-
+
var dispatch_data = {offset: search_criteria.start_row,
num_rows: search_criteria.rows_requested,
filters: filters
}
-
- if (search_criteria.sort_key) {
+
+ if (search_criteria.sort_key) {
dispatch_data["sort_col"] = search_criteria.sort_key;
dispatch_data["sort_order"] = search_criteria.sort_order;
}
- self.connector_query(
- o.resource,
- o.resource_path,
- dispatch_data,
+ self.connector_query(
+ o.resource,
+ o.resource_path,
+ dispatch_data,
results);
},
-
+
/* Signals */
ready: function(event, user_data) {
-
+
},
-
+
/* Getter/Setters */
-
+
visible_row_count: function() {
var self = this;
return self.$visible_rows.length;
},
-
+
/* Private */
_setup_template: function() {
var self = this;
var o = self.options;
-
+
var rowtemplate = jQuery('.rowtemplate', self.element);
rowtemplate.removeClass('rowtemplate')
if (rowtemplate.length)
@@ -191,16 +191,16 @@
// this also removes the template from the document
var container_div = jQuery('<div />');
var html = unescape(container_div.append(rowtemplate).html());
-
+
o.row_template = jQuery.template(html, {regx:'moksha'}).compile();
-
+
self.$headers = $('th:has(a[href])', this.element);
//self.$headers = this.$ths.map(function() { return $('a', this)[0]; });
self.$headers.unbind(o.event + '.mokshagrid').bind(o.event + '.mokshagrid', function(event) {
var ckey = o.sort_key;
var corder = o.sort_order;
var key = event.originalTarget.hash.substr(1);
-
+
if (key == ckey) {
if (corder == -1) {
corder = 1;
@@ -210,18 +210,18 @@
} else {
corder = 'decending';
}
-
+
self.options['sort_key'] = key;
self.options['sort_order'] = corder;
-
+
self.request_data_refresh();
return false;
})
-
+
self.request_data_refresh();
},
-
+
_generate_table: function() {
var self = this;
var t = $('<table />');
@@ -229,7 +229,7 @@
// get the model if there is a resource and path
if (!o.resource || !o.resource_path)
return t;
-
+
var results = function(json) {
o.sort_key = json.default_sort_col;
o.sort_order = json.default_sort_order;
@@ -238,17 +238,17 @@
var header_tr = $('<tr />');
headers.append(header_tr);
t.append(headers);
-
+
var template = $('<tbody />').addClass("rowtemplate");
var template_tr = $('<tr />');
template.append(template_tr);
t.append(template);
-
+
for (var c in json.columns) {
var c_data = json.columns[c];
if (!c_data.default_visible)
continue;
-
+
if (c_data.can_sort) {
var a = $('<a />').attr('href', '#' + c).text(c);
var th = $('<th />').append(a);
@@ -257,22 +257,22 @@
var td = $('<th />').text(c);
header_tr.append(td);
}
-
+
template_tr.append('<td>@{' + c + '}</td>');
}
-
+
self._setup_template();
}
- self.connector_query_model(
- o.resource,
- o.resource_path,
+ self.connector_query_model(
+ o.resource,
+ o.resource_path,
results);
-
+
return t;
}
})
-
+
$.extend($.ui.mokshagrid, {
version: '@VERSION',
getters: 'visible_row_count',
@@ -289,16 +289,16 @@
resource: null,
resource_path: null,
loading_throbber: ["Loading", // list of img urls or text
- "Loading.",
- "Loading..",
- "Loading..."]
+ "Loading.",
+ "Loading..",
+ "Loading..."]
}
});
-
+
$.extend( $.template.regx , {
moksha:/\@\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g
}
);
-
-
+
+
})(jQuery);
\ No newline at end of file
diff --git a/moksha/public/javascript/ui/moksha.ui.tabs.js b/moksha/public/javascript/ui/moksha.ui.tabs.js
index 406a2ac..b216610 100644
--- a/moksha/public/javascript/ui/moksha.ui.tabs.js
+++ b/moksha/public/javascript/ui/moksha.ui.tabs.js
@@ -532,17 +532,11 @@ $.widget("ui.mokshatabs", {
url: url,
success: function(r, s) {
var $panel = $(a.hash + ':first', self.element);
- var $temp = $(r);
- var $stripped = [];
- $.each($temp, function(i, s) {
- if (!$(s).is('script[src]')){
- $stripped.push(s);
- }
- });
+ var $stripped = moksha.filter_resources(r);
+
$panel.html($stripped);
cleanup();
-
if (o.cache)
$.data(a, 'cache.tabs', true); // if loaded once do not load them again
diff --git a/setup.py b/setup.py
index 5d870e5..d930a38 100644
--- a/setup.py
+++ b/setup.py
@@ -79,16 +79,17 @@ setup(
orbited = moksha.api.widgets.orbited:orbited_js
jquery = tw.jquery:jquery_js
- jquery_ui_core = tw.jquery.ui_core:jquery_ui_core_js
-
- #jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js
- #jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js
+ moksha = moksha.api.widgets.moksha:moksha_js
+ jquery_ui_core = tw.jquery.ui:ui_core_js
+ jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js
+ jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js
#jquery_ui_dialog = tw.jquery.ui:ui_dialog_min_js
#jquery_ui_tabs = tw.jquery.ui_tabs:jquery_ui_tabs_js
#jquery_json_js = fedoracommunity.widgets:jquery_json_js
#jquery_template_js = fedoracommunity.widgets:jquery_template_js
#jquery_ui_css = moksha.widgets.jquery_ui_theme:JQueryUITheme
+
# Enable support for the Blueprint CSS framework
blueprint_ie_css = moksha.widgets.blueprint:blueprint_ie_css
blueprint_screen_css = moksha.widgets.blueprint:blueprint_screen_css
@@ -98,7 +99,7 @@ setup(
#blueprint_fancytype_css = moksha.widgets.blueprint:blueprint_plugin_fancytype_css
# up up down down left right left right b a
- #konami_js = moksha.widgets.misc.ptd:konami
+ konami_js = moksha.widgets.misc.ptd:konami
[moksha.menu]
default_menu = moksha.api.menus:MokshaDefaultMenu
15 years, 4 months
start-moksha
by Luke Macken
start-moksha | 1 +
1 file changed, 1 insertion(+)
New commits:
commit ab28c407e05871ce2729d2762de09374d870efbb
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 13:50:03 2009 -0500
Install the latest setuptools, to fix a bug for mac users
diff --git a/start-moksha b/start-moksha
index fdb7875..3e6b71c 100755
--- a/start-moksha
+++ b/start-moksha
@@ -9,6 +9,7 @@ if [ ! $VIRTUAL_ENV ]; then
virtualenv tg2env
#virtualenv --no-site-packages tg2env
source tg2env/bin/activate
+ easy_install -U setuptools
easy_install -U WebOb
easy_install -U SQLAlchemy
easy_install -i http://www.turbogears.org/2.0/downloads/current/index tg.devtools
15 years, 4 months
6 commits - .gitignore moksha/api moksha/middleware moksha/streams moksha/widgets setup.py
by Luke Macken
.gitignore | 1 +
moksha/api/widgets/containers/dashboardcontainer.py | 6 ++----
moksha/middleware/middleware.py | 7 ++-----
moksha/streams/feed/feedstream.py | 12 +++++-------
moksha/widgets/container/dashboards.py | 17 -----------------
setup.py | 10 +++++-----
6 files changed, 15 insertions(+), 38 deletions(-)
New commits:
commit 187b93d1a96ba171126a6b25fcd0ca03eb196b83
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 03:38:31 2009 -0500
Some FeedStreamer module cleanups, and bugfixes
diff --git a/moksha/streams/feed/feedstream.py b/moksha/streams/feed/feedstream.py
index 9ac2f6d..5f70d40 100644
--- a/moksha/streams/feed/feedstream.py
+++ b/moksha/streams/feed/feedstream.py
@@ -16,10 +16,10 @@
# Copyright 2008, Red Hat, Inc.
# Authors: Luke Macken <lmacken(a)redhat.com>
-import moksha
import logging
-import feedparser, time, sys
-import md5, os
+import feedparser
+import time
+import os
try:
from cStringIO import cStringIO as StringIO
@@ -29,10 +29,8 @@ except ImportError:
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 datetime import timedelta
from feedcache import Cache
from shove import Shove
from tg import config
@@ -97,7 +95,7 @@ class ConditionalHTTPClientFactory(HTTPClientFactory):
log.error("Unable to store parsed_feed: %r" % parsed_feed)
log.exception(e)
- def notModified():
+ def notModified(self):
if self.waiting:
self.waiting = False
commit 87958d53f8748573947ee0a26d409bde1a4f0069
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 03:35:56 2009 -0500
Clean up some unused modules in our middleware
diff --git a/moksha/middleware/middleware.py b/moksha/middleware/middleware.py
index ea60286..4737780 100644
--- a/moksha/middleware/middleware.py
+++ b/moksha/middleware/middleware.py
@@ -20,21 +20,18 @@ import os
import moksha
import logging
import pkg_resources
-import simplejson as json
-import urllib
from tg.controllers import WSGIAppController
-from webob import Request, Response
+from webob import Request
from shove import Shove
from pylons import config
from inspect import isclass
from pylons.i18n import ugettext
from paste.deploy import appconfig
-from genshi.filters import Translator
from sqlalchemy import create_engine
from feedcache.cache import Cache
-from moksha.exc import ApplicationNotFound, MokshaException
+from moksha.exc import MokshaException
from moksha.lib.helpers import (defaultdict, get_moksha_config_path,
get_main_app_config_path)
from moksha.wsgiapp import MokshaAppDispatcher
commit 89f5683c2750a5cde4443717a6ed05932c0eea4f
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 03:33:33 2009 -0500
Remove an unnecessary module
diff --git a/moksha/widgets/container/dashboards.py b/moksha/widgets/container/dashboards.py
deleted file mode 100644
index 90211ae..0000000
--- a/moksha/widgets/container/dashboards.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from tw.api import WidgetList, Widget
-
-class MyWidgetViews(Widget):
- class views(WidgetList):
- mobi = MyMobileWidget
- sidebar = MySidebarWidget
- content = MyContentWidget
-
-
-class MyBaseWidget(Widget):
- views = MyWidgetViews
- views = {'mobi': MyMobileWidget, 'sidebar': MySidebarWidget}
-
-class MyMobileWidget(MyBaseWidget):
- template = 'mymobiletemplate'
-
-
commit ca459bf7f3eff0b430603fcb273dd189baf09e96
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 03:07:51 2009 -0500
Update our gitignore
diff --git a/.gitignore b/.gitignore
index 9a17f7d..15512a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ mokshaenv
*.db
.build
tg2env
+*.egg-info
commit 4d212e2f796bc6e473292dab7a56ce74d7c96e41
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 02:47:56 2009 -0500
Clean up some of our dashboard container imports
diff --git a/moksha/api/widgets/containers/dashboardcontainer.py b/moksha/api/widgets/containers/dashboardcontainer.py
index 04e56a4..bb1335b 100644
--- a/moksha/api/widgets/containers/dashboardcontainer.py
+++ b/moksha/api/widgets/containers/dashboardcontainer.py
@@ -1,9 +1,7 @@
-from moksha.api.widgets.layout.layout import layout_js, layout_css, ui_core_js, ui_draggable_js, ui_droppable_js, ui_sortable_js
-
+from tg import config
from tw.api import Widget
-from tw.jquery import jquery_js
+
from moksha.lib.helpers import eval_app_config, ConfigWrapper
-from tg import config
class AppListWidget(Widget):
template = 'mako:moksha.api.widgets.containers.templates.layout_applist'
commit 70dfad60d610d43d56b3a9d8c8905f9795724007
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 02:42:19 2009 -0500
Tweak our global resources and remove some unnecessary ones by default
diff --git a/setup.py b/setup.py
index 7aa603d..5d870e5 100644
--- a/setup.py
+++ b/setup.py
@@ -79,14 +79,14 @@ setup(
orbited = moksha.api.widgets.orbited:orbited_js
jquery = tw.jquery:jquery_js
- jquery_ui_core = tw.jquery.ui:ui_core_js
- jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js
- jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js
+ jquery_ui_core = tw.jquery.ui_core:jquery_ui_core_js
+
+ #jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js
+ #jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js
#jquery_ui_dialog = tw.jquery.ui:ui_dialog_min_js
#jquery_ui_tabs = tw.jquery.ui_tabs:jquery_ui_tabs_js
#jquery_json_js = fedoracommunity.widgets:jquery_json_js
#jquery_template_js = fedoracommunity.widgets:jquery_template_js
-
#jquery_ui_css = moksha.widgets.jquery_ui_theme:JQueryUITheme
# Enable support for the Blueprint CSS framework
@@ -98,7 +98,7 @@ setup(
#blueprint_fancytype_css = moksha.widgets.blueprint:blueprint_plugin_fancytype_css
# up up down down left right left right b a
- konami_js = moksha.widgets.misc.ptd:konami
+ #konami_js = moksha.widgets.misc.ptd:konami
[moksha.menu]
default_menu = moksha.api.menus:MokshaDefaultMenu
15 years, 4 months
moksha/api
by Luke Macken
moksha/api/widgets/feed/feed.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
New commits:
commit 226bc3d7407ce93455d36fc6a0fe32564b3b6f56
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 01:22:29 2009 -0500
Allow the feed id to be passed into the iterentries 'd' argument
diff --git a/moksha/api/widgets/feed/feed.py b/moksha/api/widgets/feed/feed.py
index 11b7617..e8c83a4 100644
--- a/moksha/api/widgets/feed/feed.py
+++ b/moksha/api/widgets/feed/feed.py
@@ -64,6 +64,7 @@ class Feed(Widget):
def iterentries(self, d=None, limit=None):
url = self.url or d.get('url')
+ id = d and d.get('id', self.id) or self.id
if moksha.feed_cache:
feed = moksha.feed_cache.fetch(url)
else:
@@ -88,7 +89,7 @@ class Feed(Widget):
d['title'] = 'Unable to parse feed'
return
for i, entry in enumerate(feed.get('entries', [])):
- entry['uid'] = '%s_%d' % (self.id, i)
+ entry['uid'] = '%s_%d' % (id, i)
entry['link'] = entry.get('link')
if i == limit:
break
15 years, 4 months
moksha/api
by Luke Macken
moksha/api/widgets/feed/feed.py | 16 ++++++----------
moksha/api/widgets/feed/live.py | 10 +++++++---
2 files changed, 13 insertions(+), 13 deletions(-)
New commits:
commit 7541ecb311b51a0eeacaa9d6492a6c995fa013da
Author: Luke Macken <lmacken(a)redhat.com>
Date: Wed Feb 18 00:59:36 2009 -0500
Fix entry limiting in our feed widget stack
diff --git a/moksha/api/widgets/feed/feed.py b/moksha/api/widgets/feed/feed.py
index 104f564..11b7617 100644
--- a/moksha/api/widgets/feed/feed.py
+++ b/moksha/api/widgets/feed/feed.py
@@ -62,7 +62,7 @@ class Feed(Widget):
return super(Feed, cls).__new__(AlternateFeedView, *args, **kw)
return super(Feed, cls).__new__(cls, *args, **kw)
- def iterentries(self, d=None):
+ def iterentries(self, d=None, limit=None):
url = self.url or d.get('url')
if moksha.feed_cache:
feed = moksha.feed_cache.fetch(url)
@@ -90,6 +90,8 @@ class Feed(Widget):
for i, entry in enumerate(feed.get('entries', [])):
entry['uid'] = '%s_%d' % (self.id, i)
entry['link'] = entry.get('link')
+ if i == limit:
+ break
yield entry
def entries(self):
@@ -101,15 +103,9 @@ class Feed(Widget):
def update_params(self, d):
super(Feed, self).update_params(d)
d['entries'] = []
- limit = d.get('show')
- if limit:
- for i, entry in enumerate(self.iterentries(d)):
- if i >= limit:
- break
- d['entries'].append(entry)
- else:
- for entry in self.iterentries(d):
- d['entries'].append(entry)
+ limit = d.get('limit')
+ for entry in self.iterentries(d, limit=limit):
+ d['entries'].append(entry)
def close(self):
global feed_storage
diff --git a/moksha/api/widgets/feed/live.py b/moksha/api/widgets/feed/live.py
index 3b869fb..263443b 100644
--- a/moksha/api/widgets/feed/live.py
+++ b/moksha/api/widgets/feed/live.py
@@ -25,8 +25,10 @@ class LiveFeedWidget(LiveWidget):
'url': 'The feed URL',
'topic': 'A topic or list of topics to subscribe to',
'feed': 'A moksha Feed object',
+ 'd': 'The widget data',
+ 'limit': 'The number of entries to display',
}
- template = '${feed(id=id, url=url)}'
+ template = '${feed(id=id, url=url, limit=limit)}'
onmessage = """
$.each(json, function() {
$("#${id} ul li:last").remove();
@@ -39,8 +41,10 @@ class LiveFeedWidget(LiveWidget):
"""
feed = Feed()
topic = None
+ limit = 10
def update_params(self, d):
+ if not d.get('topic'):
+ d['topic'] = 'feed.%s' % d.get('url', self.url)
super(LiveFeedWidget, self).update_params(d)
- if not d.topic:
- d.topic = 'feed.%s' % d.url
+ d.d = d
15 years, 4 months