You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by rj...@apache.org on 2013/05/30 20:44:31 UTC
svn commit: r1487964 -
/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
Author: rjollos
Date: Thu May 30 18:44:31 2013
New Revision: 1487964
URL: http://svn.apache.org/r1487964
Log:
Removed excess whitespace, fixed indentation and removed unnecessary backslash characters.
Modified:
bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
Modified: bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py?rev=1487964&r1=1487963&r2=1487964&view=diff
==============================================================================
--- bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py (original)
+++ bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py Thu May 30 18:44:31 2013
@@ -26,9 +26,9 @@ Implementing dashboard user interface.
__metaclass__ = type
-from itertools import izip
+import copy
import pkg_resources
-import re, copy
+import re
from uuid import uuid4
from genshi.builder import tag
@@ -49,16 +49,17 @@ from bhdashboard.api import DashboardSys
from bhdashboard import _json
from multiproduct.env import ProductEnvironment
+
class DashboardModule(Component):
"""Web frontend for dashboard infrastructure.
"""
- implements(IRequestHandler, IRequestFilter, INavigationContributor, \
- ITemplateProvider)
+ implements(IRequestHandler, IRequestFilter, INavigationContributor,
+ ITemplateProvider)
- mainnav_label = Option('mainnav', 'tickets.label', 'Tickets', \
- """Dashboard label in mainnav""")
- default_widget_height = IntOption('widgets', 'default_height', 320, \
- """Default widget height in pixels""")
+ mainnav_label = Option('mainnav', 'tickets.label', 'Tickets',
+ """Dashboard label in mainnav""")
+ default_widget_height = IntOption('widgets', 'default_height', 320,
+ """Default widget height in pixels""")
# IRequestFilter methods
@@ -70,21 +71,21 @@ class DashboardModule(Component):
def post_process_request(self, req, template, data, content_type):
"""Inject dashboard helpers in data.
"""
- if data is not None :
+ if data is not None:
data['bhdb'] = DashboardChrome(self.env)
if isinstance(req.perm.env, ProductEnvironment) \
- and not 'resourcepath_template' in data \
- and 'product_list' in data:
+ and not 'resourcepath_template' in data \
+ and 'product_list' in data:
data['resourcepath_template'] = 'bh_path_general.html'
for item in req.chrome['nav'].get('mainnav', []):
self.log.debug('%s' % (item,))
if item['name'] == 'tickets':
item['label'] = tag.a(_(self.mainnav_label),
- href=req.href.dashboard())
+ href=req.href.dashboard())
if item['active'] and \
not ReportModule(self.env).match_request(req):
add_ctxtnav(req, _('Reports'),
- href=req.href.report())
+ href=req.href.report())
break
return template, data, content_type
@@ -95,29 +96,26 @@ class DashboardModule(Component):
def process_request(self, req):
req.perm.require('PRODUCT_VIEW')
- """Initially this will render static widgets. With time it will be
- more and more dynamic and flexible.
- """
+ # Initially this will render static widgets. With time it will be
+ # more and more dynamic and flexible.
if self.env[QueryModule] is not None:
add_ctxtnav(req, _('Custom Query'), req.href.query())
if self.env[ReportModule] is not None:
add_ctxtnav(req, _('Reports'), req.href.report())
context = Context.from_request(req)
- template, layout_data = self.expand_layout_data(context,
+ template, layout_data = self.expand_layout_data(context,
'bootstrap_grid',
self.DASHBOARD_SCHEMA if isinstance(self.env, ProductEnvironment)
- else self.DASHBOARD_GLOBAL_SCHEMA
- )
+ else self.DASHBOARD_GLOBAL_SCHEMA
+ )
widgets = self.expand_widget_data(context, layout_data)
return template, {
- 'context' : Context.from_request(req),
- 'layout' : layout_data,
- 'widgets' : widgets,
- 'title' : _(self.mainnav_label),
- 'default' : {
- 'height' : self.default_widget_height or None
- }
- }, None
+ 'context': Context.from_request(req),
+ 'layout': layout_data,
+ 'widgets': widgets,
+ 'title': _(self.mainnav_label),
+ 'default': {'height': self.default_widget_height or None}
+ }, None
# INavigationContributor methods
def get_active_navigation_item(self, req):
@@ -135,11 +133,9 @@ class DashboardModule(Component):
"""List `htdocs` dirs for dashboard and widgets.
"""
resource_filename = pkg_resources.resource_filename
- return [
- ('dashboard', resource_filename('bhdashboard', 'htdocs')),
- #('widgets', resource_filename('bhdashboard.widgets', 'htdocs'))
- ('layouts', resource_filename('bhdashboard.layouts', 'htdocs'))
- ]
+ return [('dashboard', resource_filename('bhdashboard', 'htdocs')),
+ #('widgets', resource_filename('bhdashboard.widgets', 'htdocs'))
+ ('layouts', resource_filename('bhdashboard.layouts', 'htdocs'))]
def get_templates_dirs(self):
"""List `templates` folders for dashboard and widgets.
@@ -151,44 +147,44 @@ class DashboardModule(Component):
# Temp vars
DASHBOARD_SCHEMA = {
- 'div' : [
+ 'div': [
{
- '_class' : 'row',
- 'div' : [
+ '_class': 'row',
+ 'div': [
{
- '_class' : 'span8',
- 'widgets' : ['my tickets', 'active tickets',
- 'products', 'versions',
- 'milestones', 'components']
+ '_class': 'span8',
+ 'widgets': ['my tickets', 'active tickets',
+ 'products', 'versions',
+ 'milestones', 'components']
},
{
- '_class' : 'span4',
- 'widgets' : ['activity']
+ '_class': 'span4',
+ 'widgets': ['activity']
}
]
}
],
- 'widgets' : {
+ 'widgets': {
'components': {
- 'args' : [
+ 'args': [
'TicketFieldValues',
None,
- {'args' : {
- 'field' : 'component',
- 'title' : 'Components',
- 'verbose' : True}}]
+ {'args': {
+ 'field': 'component',
+ 'title': 'Components',
+ 'verbose': True}}]
},
'milestones': {
- 'args' : [
+ 'args': [
'TicketFieldValues',
None,
- {'args' : {
- 'field' : 'milestone',
- 'title' : 'Milestones',
- 'verbose' : True}}]
+ {'args': {
+ 'field': 'milestone',
+ 'title': 'Milestones',
+ 'verbose': True}}]
},
'versions': {
- 'args' : [
+ 'args': [
'TicketFieldValues',
None,
{'args' : {
@@ -197,38 +193,38 @@ class DashboardModule(Component):
'verbose' : True}}]
},
'active tickets': {
- 'args' : [
+ 'args': [
'TicketQuery',
None,
- {'args' : {
+ {'args': {
'max' : 10,
- 'query' : 'status=!closed&group=milestone'\
- '&col=id&col=summary&col=owner' \
- '&col=status&col=priority&' \
+ 'query': 'status=!closed&group=milestone'
+ '&col=id&col=summary&col=owner'
+ '&col=status&col=priority&'
'order=priority',
- 'title' : 'Active Tickets'}}],
- 'altlinks' : False
+ 'title': 'Active Tickets'}}],
+ 'altlinks': False
},
'my tickets': {
- 'args' : [
+ 'args': [
'TicketQuery',
None,
- {'args' : {
- 'max' : 10,
- 'query' : 'status=!closed&group=milestone'\
- '&col=id&col=summary&col=owner' \
- '&col=status&col=priority&' \
- 'order=priority&' \
- 'owner=$USER',
- 'title' : 'My Tickets'}
+ {'args': {
+ 'max': 10,
+ 'query': 'status=!closed&group=milestone'
+ '&col=id&col=summary&col=owner'
+ '&col=status&col=priority&'
+ 'order=priority&'
+ 'owner=$USER',
+ 'title': 'My Tickets'}
}],
- 'altlinks' : False
+ 'altlinks': False
},
'activity': {
- 'args' : ['Timeline', None, {'args' : {}}]
+ 'args': ['Timeline', None, {'args': {}}]
},
'products': {
- 'args' : ['Product', None, {'args': { 'max': 3 }}]
+ 'args': ['Product', None, {'args': {'max': 3}}]
},
}
}
@@ -255,47 +251,49 @@ class DashboardModule(Component):
layout = DashboardSystem(self.env).resolve_layout(layout_name)
template = layout.expand_layout(layout_name, context, {
- 'schema' : schema,
- 'embed' : embed
- })['template']
+ 'schema': schema,
+ 'embed': embed
+ })['template']
return template, schema
def _render_widget(self, wp, name, ctx, options):
"""Render widget without failing.
"""
- try :
- if wp is None :
+ try:
+ if wp is None:
raise InvalidIdentifier("Unknown widget ID")
return wp.render_widget(name, ctx, options)
except Exception, exc:
log_entry = str(uuid4())
exccls = exc.__class__
- self.log.exception("- %s - Error rendering widget %s with options %s",
- log_entry, name, options)
+ self.log.exception(
+ "- %s - Error rendering widget %s with options %s",
+ log_entry, name, options)
data = {
- 'msgtype' : 'error',
- 'msglabel' : 'Error',
- 'msgbody' : _('Exception raised while rendering widget. '
- 'Contact your administrator for further details.'),
- 'msgdetails' : [
- ('Widget name', name),
- ('Exception type', tag.code(exccls.__name__)),
- ('Log entry ID', log_entry),
- ],
- }
- return 'widget_alert.html', \
- { 'title' : _('Widget error'), 'data' : data}, \
- ctx
+ 'msgtype': 'error',
+ 'msglabel': 'Error',
+ 'msgbody': _('Exception raised while rendering widget. '
+ 'Contact your administrator for further details.'),
+ 'msgdetails': [
+ ('Widget name', name),
+ ('Exception type', tag.code(exccls.__name__)),
+ ('Log entry ID', log_entry),
+ ],
+ }
+ return 'widget_alert.html', {
+ 'title': _('Widget error'),
+ 'data': data
+ }, ctx
def expand_widget_data(self, context, schema):
"""Expand raw widget data and format it for use in template
"""
# TODO: Implement dynamic dashboard specification
widgets_spec = schema.get('widgets', {})
- widgets_index = dict([wnm, wp] \
- for wp in DashboardSystem(self.env).widget_providers \
- for wnm in wp.get_widgets()
- )
+ widgets_index = dict([wnm, wp]
+ for wp in DashboardSystem(self.env).widget_providers
+ for wnm in wp.get_widgets()
+ )
self.log.debug("Bloodhound: Widget index %s" % (widgets_index,))
for w in widgets_spec.itervalues():
w['c'] = widgets_index.get(w['args'][0])
@@ -303,13 +301,16 @@ class DashboardModule(Component):
self.log.debug("Bloodhound: Widget specs %s" % (widgets_spec,))
chrome = Chrome(self.env)
render = chrome.render_template
- data_strm = ( (k, w, self._render_widget(w['c'], *w['args'])) \
- for k,w in widgets_spec.iteritems())
- return dict([k, {'title' : data['title'],
- 'content' : render(wctx.req, template, data['data'], fragment=True),
- 'ctxtnav' : w.get('ctxtnav', True) and data.get('ctxtnav') or None,
- 'altlinks' : w.get('altlinks', True) and data.get('altlinks') or None}] \
- for k, w, (template, data, wctx) in data_strm)
+ data_strm = ((k, w, self._render_widget(w['c'], *w['args']))
+ for k, w in widgets_spec.iteritems())
+ return dict([k, {'title': data['title'],
+ 'content': render(wctx.req, template, data['data'],
+ fragment=True),
+ 'ctxtnav': w.get('ctxtnav', True) and
+ data.get('ctxtnav') or None,
+ 'altlinks': w.get('altlinks', True) and
+ data.get('altlinks') or None}
+ ] for k, w, (template, data, wctx) in data_strm)
def alert_disabled(self):
return tag.div(tag.span('Error', class_='label label-important'),
@@ -324,6 +325,7 @@ class DashboardModule(Component):
XMLNS_DASHBOARD_UI = 'http://issues.apache.org/bloodhound/wiki/Ui/Dashboard'
+
class DashboardChrome:
"""Helper functions providing access to dashboard infrastructure
in Genshi templates. Useful to reuse layouts and widgets across
@@ -353,14 +355,14 @@ class DashboardChrome:
else:
widgets = {}
schema['widgets'] = widgets
- template, layout_data = dbmod.expand_layout_data(
- context, layout, schema, True)
+ template, layout_data = dbmod.expand_layout_data(context, layout,
+ schema, True)
widgets = dbmod.expand_widget_data(context, layout_data)
- return Chrome(self.env).render_template(context.req, template,
- dict(context=context, layout=layout_data,
- widgets=widgets, title='',
- default={'height':dbmod.default_widget_height or None}),
- fragment=True)
+ return Chrome(self.env).render_template(
+ context.req, template,
+ dict(context=context, layout=layout_data, widgets=widgets, title='',
+ default={'height': dbmod.default_widget_height or None}),
+ fragment=True)
def expand_widget(self, context, widget):
"""Render single widget
@@ -375,15 +377,13 @@ class DashboardChrome:
options['args'] = _json.loads(argsdef)
elif isinstance(argsdef, Stream):
options['args'] = parse_args_tag(argsdef)
- return dbmod.expand_widget_data(
- context,
- {'widgets' : { 0 : widget }}
- )[0]
+ return dbmod.expand_widget_data(context, {'widgets': {0: widget}})[0]
#------------------------------------------------------
# Stream processors
#------------------------------------------------------
+
def parse_args_tag(stream):
"""Parse Genshi Markup for widget arguments
"""
@@ -396,11 +396,11 @@ def parse_args_tag(stream):
qname, attrs = data
if qname.namespace == XMLNS_DASHBOARD_UI \
and qname.localname == 'arg':
- if inside :
+ if inside:
raise RuntimeError('Nested bh:arg tag')
else:
argnm = attrs.get('name')
- argvalue = ''
+ argvalue = ''
inside = True
elif kind == Stream.TEXT:
argvalue += data
@@ -410,4 +410,3 @@ def parse_args_tag(stream):
args[argnm] = argvalue
inside = False
return args
-