incubator-bloodhound-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From g..@apache.org
Subject svn commit: r1307970 - in /incubator/bloodhound/trunk/bloodhound_dashboard: ./ bhdashboard/ bhdashboard/templates/ bhdashboard/widgets/ bhdashboard/widgets/templates/
Date Sun, 01 Apr 2012 01:01:03 GMT
Author: gjm
Date: Sun Apr  1 01:01:02 2012
New Revision: 1307970

URL: http://svn.apache.org/viewvc?rev=1307970&view=rev
Log:
Dashboard code import: BH_Dashboard: Introducing timeline (activity) widget

Added:
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
  (with props)
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py   (with
props)
Modified:
    incubator/bloodhound/trunk/bloodhound_dashboard/TODO
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bhdb_one_col.html
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/util.py
    incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/TODO
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/TODO?rev=1307970&r1=1307969&r2=1307970&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/TODO (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/TODO Sun Apr  1 01:01:02 2012
@@ -15,3 +15,16 @@ description = Provide an extension point
       - Banner + two columns layouts
 keywords = dashboard extension layout interface
 
+[ticket/t2]
+id =
+summary = Insert pagination links in tickets report widget
+description = Insert pagination links in tickets report widget
+keywords = dashboard widget ticket report pagination
+
+[ticket/t3]
+id = 
+summary = Insert altlikns at the bottom of widgets
+description = Provide a separate panel at the bottom of widgets 
+    so as to display alternate (e.g. download) links.
+keywords = dashboard download alternate navigation
+

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py?rev=1307970&r1=1307969&r2=1307970&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/api.py Sun Apr  1 01:01:02
2012
@@ -23,12 +23,21 @@ r"""Project dashboard for Apache(TM) Blo
 
 The core of the dashboard architecture.
 """
+__metaclass__ = type
+
+from datetime import date, time, datetime, timedelta
 
 from trac.core import Component, ExtensionPoint, implements, \
         Interface, TracError
 from trac.perm import IPermissionRequestor
+from trac.util.compat import set
+from trac.util.datefmt import parse_date
 from trac.util.translation import _
 
+#--------------------------------------
+# Core classes and interfaces
+#--------------------------------------
+
 class IWidgetProvider(Interface):
     r"""Extension point interface for components providing widgets.
     These may be seen as web parts more sophisticated than WikiMacro 
@@ -88,6 +97,10 @@ class DashboardSystem(Component):
                     return None
         return (get_and_check(param) for param in params)
 
+#--------------------------------------
+# Exfeption classes
+#--------------------------------------
+
 # Maybe it is better to move these to a separate file 
 # (if this gets as big as it seems it will be)
 
@@ -112,3 +125,81 @@ class InvalidWidgetArgument(WidgetExcept
         return unicode(_("Invalid argument `") + self.argname + "`. " + \
                 self.message)
 
+#--------------------------------------
+# Default field types
+#--------------------------------------
+
+class DateField:
+    """Convert datetime field
+    """
+    def __init__(self, fmt="%Y-%m-%d %H:%M:%S", tz=None):
+        """Initialize datetime field converter
+
+        :param fmt:       format string used to interpret dates and times
+        """
+        self.fmt = fmt
+        self.tz = tz
+
+    def __call__(self, value, fmt=None):
+        """Perform the actual conversion
+        """
+        if isinstance(value, (date, time, datetime, timedelta)):
+            return value
+        elif isinstance(value, basestring):
+            try:
+                return parse_date(value, self.tz)
+            except TracError, exc:
+                try:
+                    fmt = fmt or self.fmt
+                    return datetime.strptime(value, fmt)
+                except:
+                    raise InvalidWidgetArgument(
+                            error=exc, title=_('Datetime conversion error'))
+        elif isinstance(value, int):
+            return datetime.utcfromtimestamp(value)
+        else:
+            raise InvalidWidgetArgument(
+                    "Invalid format `%s` for value `%s`" % (fmt, value),
+                    title=_('Datetime conversion error'))
+
+class ListField:
+    """Convert list field
+    """
+    def __init__(self, sep=','):
+        """Initialize list field converter
+
+        :param sep:       character used to delimit list items
+        """
+        self.sep = sep
+
+    def __call__(self, value):
+        """Perform the actual conversion
+        """
+        if isinstance(value, basestring):
+            return value.split(self.sep)
+        else:
+            try:
+                return list(value)
+            except Exception, exc:
+                raise InvalidWidgetArgument(error=exc, 
+                        title=_('List conversion error'))
+
+class EnumField:
+    """Convert enum field
+    """
+    def __init__(self, *choices):
+        """Initialize enum field converter
+
+        :param choices:       allowed values
+        """
+        self.choices = set(choices)
+
+    def __call__(self, value):
+        """Perform the actual conversion
+        """
+        if value not in self.choices:
+            raise InvalidWidgetArgument(
+                _('Expected one of `%s` but got `%s`') % (self.choices, value),
+                title=_('Enum conversion error'))
+        return value
+

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bhdb_one_col.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bhdb_one_col.html?rev=1307970&r1=1307969&r2=1307970&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bhdb_one_col.html
(original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/templates/bhdb_one_col.html
Sun Apr  1 01:01:02 2012
@@ -13,6 +13,11 @@
         overflow: auto;
       }
     </style>
+    <style>
+      .ui-box {
+        margin: 10px;
+      }
+    </style>
   </head>
   <body class="yui-skin-sam">
     <div id="doc3" class="yui-t7">

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/util.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/util.py?rev=1307970&r1=1307969&r2=1307970&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/util.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/util.py Sun Apr  1 01:01:02
2012
@@ -39,6 +39,7 @@ from bhdashboard.api import DashboardSys
 def dummy_request(env, uname=None):
     environ = {
                 'trac.base_url' : str(env._abs_href()), 
+                'REQUEST_METHOD' : 'GET',
                 'SCRIPT_NAME' : urlparse(str(env._abs_href())).path
                 }
     req = Request(environ, lambda *args, **kwds: None)

Modified: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py?rev=1307970&r1=1307969&r2=1307970&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py (original)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/web_ui.py Sun Apr  1 01:01:02
2012
@@ -105,12 +105,23 @@ class DashboardModule(Component):
         """
         # TODO: Implement dynamic dashboard specification
         from bhdashboard.widgets.report import TicketReportWidget
-        w = TicketReportWidget(self.env)
+        from bhdashboard.widgets.timeline import TimelineWidget
+
         ctx = Context.from_request(req)
-        args = ('TicketReport', ctx, {'args' : {'id' : 3}})
+        widgets_spec = [
+                {
+                    'c' : TicketReportWidget(self.env), 
+                    'args' : ['TicketReport', ctx, {'args' : {'id' : 3}}]
+                },
+                {
+                    'c' : TimelineWidget(self.env),
+                    'args' : ['Timeline', ctx, {'args' : {'max' : 10}}]
+                }
+            ]
         chrome = Chrome(self.env)
-        template, data, _ = w.render_widget(*args)
         render = chrome.render_template
+        data_strm = (w['c'].render_widget(*w['args']) for w in widgets_spec)
         return [{'title' : data['title'], 
-                'content' : render(req, template, data['data'], fragment=True)}]
+                'content' : render(req, template, data['data'], fragment=True)} \
+                for template, data, _ in data_strm]
 

Added: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html?rev=1307970&view=auto
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
(added)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
Sun Apr  1 01:01:02 2012
@@ -0,0 +1,24 @@
+
+<div id="content" class="timeline"
+  xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:py="http://genshi.edgewall.org/"
+  xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <py:for each="day, events in groupby(events, key=lambda e: format_date(e.date))">
+    <h2>${day}: ${day == today and 'Today' or day == yesterday and 'Yesterday' or None}</h2>
+    <dl>
+      <py:for each="event in events"
+        py:with="highlight = precision and precisedate and timedelta(0) &lt;= (event.date
- precisedate) &lt; precision">
+        <dt class="${classes(event.kind, highlight=highlight)}">
+          <a href="${event.render('url', context)}">
+            <span class="time">${format_time(event.date, str('%H:%M'))}</span>
${event.render('title', context)}
+            <py:if test="event.author">by <span class="author">${format_author(event.author)}</span></py:if>
+          </a>
+        </dt>
+        <dd class="${classes(event.kind, highlight=highlight)}">
+          ${event.render('description', context)}
+        </dd>
+      </py:for>
+    </dl>
+  </py:for>
+</div>

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/templates/widget_timeline.html
------------------------------------------------------------------------------
    svn:mime-type = text/html

Added: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py?rev=1307970&view=auto
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py (added)
+++ incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py Sun Apr
 1 01:01:02 2012
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+
+r"""Project dashboard for Apache(TM) Bloodhound
+
+Widgets displaying timeline data.
+"""
+
+from datetime import datetime, date, time
+from itertools import imap, islice
+
+from genshi.builder import tag
+from trac.core import implements, TracError
+from trac.timeline.web_ui import TimelineModule
+from trac.util.translation import _
+
+from bhdashboard.api import DateField, EnumField, ListField
+from bhdashboard.util import WidgetBase, InvalidIdentifier, \
+                              check_widget_name, dummy_request, \
+                              pretty_wrapper, trac_version, trac_tags
+
+class TimelineWidget(WidgetBase):
+    """Display activity feed.
+    """
+    def get_widget_params(self, name):
+        """Return a dictionary containing arguments specification for
+        the widget with specified name.
+        """
+        return {
+                'from' : {
+                        'desc' : """Display events before this date""",
+                        'type' : DateField(), # TODO: Custom datetime format
+                    },
+                'daysback' : {
+                        'desc' : """Event time window""",
+                        'type' : int, 
+                    },
+                'precision' : {
+                        'desc' : """Time precision""",
+                        'type' : EnumField('second', 'minute', 'hour')
+                    },
+                'doneby' : {
+                        'desc' : """Filter events related to user""",
+                    },
+                'filters' : {
+                        'desc' : """Event filters""",
+                        'type' : ListField()
+                    },
+                'max' : {
+                        'default' : 0,
+                        'desc' : """Limit the number of events displayed""",
+                        'type' : int
+                    },
+            }
+    get_widget_params = pretty_wrapper(get_widget_params, check_widget_name)
+
+    def render_widget(self, name, context, options):
+        """Gather timeline events and render data in compact view
+        """
+        data = None
+        req = context.req
+        try:
+            params = ('from', 'daysback', 'doneby', 'precision', 'filters', \
+                        'max')
+            start, days, user, precision, filters, count = \
+                    self.bind_params(name, options, *params)
+
+            mockreq = dummy_request(self.env, req.authname)
+            mockreq.args = {
+                    'author' : user or '',
+                    'daysback' : days or '',
+                    'max' : count,
+                    'precision' : precision,
+                    'user' : user
+                }
+            if start is not None:
+                mockreq.args['from'] = start.strftime('%x %X')
+
+            timemdl = self.env[TimelineModule]
+            if timemdl is None :
+                raise TracError('Timeline module not available (disabled?)')
+
+            data = timemdl.process_request(mockreq)[1]
+        except TracError, exc:
+            if data is not None:
+                exc.title = data.get('title', 'TracReports')
+            raise
+        else:
+            return 'widget_timeline.html', \
+                    {
+                        'title' : _('Activity'),
+                        'data' : data
+                    }, \
+                    context
+
+    render_widget = pretty_wrapper(render_widget, check_widget_name)
+

Propchange: incubator/bloodhound/trunk/bloodhound_dashboard/bhdashboard/widgets/timeline.py
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message