[rhmessaging-commits] rhmessaging commits: r1540 - in mgmt: cumin/python/wooly and 1 other directories.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Tue Jan 8 00:19:48 EST 2008


Author: justi9
Date: 2008-01-08 00:19:48 -0500 (Tue, 08 Jan 2008)
New Revision: 1540

Modified:
   mgmt/cumin/python/cumin/client.py
   mgmt/cumin/python/cumin/client.strings
   mgmt/cumin/python/cumin/exchange.py
   mgmt/cumin/python/cumin/exchange.strings
   mgmt/cumin/python/cumin/queue.py
   mgmt/cumin/python/cumin/queue.strings
   mgmt/cumin/python/cumin/widgets.py
   mgmt/cumin/python/cumin/widgets.strings
   mgmt/cumin/python/wooly/tables.py
   mgmt/cumin/python/wooly/tables.strings
   mgmt/notes/justin-todo.txt
Log:
Big change to tables.  Migrates to custom-query mapped tables for
queues, exchanges, clients, and client sessions.

Apart from a problem with null rates, corrects the sorting of rate
columns.

Fixes a pagination problem.

Changes the visual position of the paginator in table views and adds a
view summary.

Updates todos.



Modified: mgmt/cumin/python/cumin/client.py
===================================================================
--- mgmt/cumin/python/cumin/client.py	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/client.py	2008-01-08 05:19:48 UTC (rev 1540)
@@ -1,5 +1,7 @@
 from wooly import *
 from wooly.widgets import *
+from wooly.tables import *
+from datetime import datetime
 
 from stat import *
 from widgets import *
@@ -13,11 +15,6 @@
     def __init__(self, app, name):
         super(ClientSet, self).__init__(app, name)
 
-        self.unit = StateSwitch(app, "unit")
-        self.unit.add_state("f", "Frames")
-        self.unit.add_state("b", "Bytes")
-        self.add_child(self.unit)
-
         self.table_sql = "client as l"
         self.where_sql = "where l.vhost_id = %(id)r"
 
@@ -26,29 +23,41 @@
 
         self.add_sql_column("id", "l.id")
         self.add_sql_column("addr", "l.address")
-        self.add_sql_column("cbsent", "c.bytes_from_client")
-        self.add_sql_column("cfsent", "c.frames_from_client")
-        self.add_sql_column("cbrecv", "c.bytes_to_client")
-        self.add_sql_column("cfrecv", "c.frames_to_client")
-        self.add_sql_column("ctime", "c.rec_time")
-        self.add_sql_column("pbsent", "p.bytes_from_client")
-        self.add_sql_column("pfsent", "p.frames_from_client")
-        self.add_sql_column("pbrecv", "p.bytes_to_client")
-        self.add_sql_column("pfrecv", "p.frames_to_client")
-        self.add_sql_column("ptime", "p.rec_time")
+        self.add_sql_column("bs",
+                            "(c.bytes_from_client - p.bytes_from_client)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("fs",
+                            "(c.frames_from_client - p.frames_from_client)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("br",
+                            "(c.bytes_to_client - p.bytes_to_client)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("fr",
+                            "(c.frames_to_client - p.frames_to_client)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
 
+        col = CheckboxColumn(app, "id")
+        self.add_column(col)
+
         col = self.AddressColumn(app, "addr")
         self.add_column(col)
 
+        self.set_selected_column(col)
+
         #col = self.SessionsColumn(app, "sess")
         #self.add_column(col)
 
         col = self.SentColumn(app, "sent")
         self.add_column(col)
 
-        col = self.ReceivedColumn(app, "recv")
+        col = self.ReceivedColumn(app, "received")
         self.add_column(col)
 
+        self.unit = StateSwitch(app, "unit")
+        self.unit.add_state("b", "Bytes")
+        self.unit.add_state("f", "Frames")
+        self.add_child(self.unit)
+
     def get_title(self, session, vhost):
         return "Clients %s" % fmt_count(self.get_item_count(session, vhost))
 
@@ -61,65 +70,51 @@
     def get_sql_values(self, session, vhost):
         return {"id": vhost.id}
 
-    class AddressColumn(ItemTableColumn):
+    class AddressColumn(SqlTableColumn):
         def get_title(self, session, vhost):
             return "Address"
 
-        def do_render(self, session, data):
+        def render_content(self, session, data):
             client = Identifiable(data["id"])
             branch = session.branch()
             self.frame().show_client(branch, client).show_view(branch)
-            content = fmt_olink(branch, client, name=data["addr"])
-            return "<td>%s</td>" % content
+            return fmt_olink(branch, client, name=data["addr"])
 
-    class SessionsColumn(ItemTableColumn):
+    class SessionsColumn(SqlTableColumn):
         def get_title(self, session, vhost):
             return "Sessions"
 
-        def do_render(self, session, data):
+        def render_content(self, session, data):
             client = Identifiable(data["id"])
             branch = session.branch()
             frame = self.frame().show_client(branch, client)
             frame.show_view(branch).show_sessions(branch)
-            content = fmt_link(branch.marshal(), client.sessions.count())
-            return "<td>%s</td>" % content
+            # XXX client.sessions won't work
+            #return fmt_link(branch.marshal(), client.sessions.count())
+            return "XXX"
 
-    class SentColumn(ItemTableColumn):
+    class SentColumn(SqlTableColumn):
         def get_title(self, session, vhost):
             return "%s Sent" % self.parent.get_unit_plural(session)
 
-        def do_render(self, session, data):
+        def get_column_key(self, session):
             unit = self.parent.unit.get(session)
+            return unit == "b" and "bs" or "fs"
 
-            csecs = secs(data["ctime"])
-            psecs = secs(data["ptime"])
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
 
-            if unit == "b":
-                value = calc_rate(data["cbsent"], data["pbsent"], csecs, psecs)
-            else:
-                value = calc_rate(data["cfsent"], data["pfsent"], csecs, psecs)
-
-            content = fmt_rate(value, unit == "b" and "byte" or "frame", "sec")
-            return "<td>%s</td>" % content
-
-    class ReceivedColumn(ItemTableColumn):
+    class ReceivedColumn(SqlTableColumn):
         def get_title(self, session, vhost):
             return "%s Received" % self.parent.get_unit_plural(session)
 
-        def do_render(self, session, data):
+        def get_column_key(self, session):
             unit = self.parent.unit.get(session)
+            return unit == "b" and "br" or "fr"
 
-            csecs = secs(data["ctime"])
-            psecs = secs(data["ptime"])
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
 
-            if unit == "b":
-                value = calc_rate(data["cbrecv"], data["pbrecv"], csecs, psecs)
-            else:
-                value = calc_rate(data["cfrecv"], data["pfrecv"], csecs, psecs)
-
-            content = fmt_rate(value, unit == "b" and "byte" or "frame", "sec")
-            return "<td>%s</td>" % content
-
 class ClientFrame(CuminFrame):
     def __init__(self, app, name):
         super(ClientFrame, self).__init__(app, name)
@@ -290,18 +285,18 @@
     def get_item_count(self, session, client):
         return client.sessions.count()
 
-    class NameColumn(ItemTableColumn):
+    class NameColumn(SqlTableColumn):
         def get_title(self, session, object):
             return "Name"
 
-    class ExpiresColumn(ItemTableColumn):
+    class ExpiresColumn(SqlTableColumn):
         def get_title(self, session, object):
             return "Expires"
 
-        def do_render(self, session, data):
-            return "<td>%s</td>" % data[self.name]
+        def render_value(self, session, value):
+            return fmt_datetime(datetime.fromtimestamp(value / 1000000000))
 
-    class StatusColumn(ItemTableColumn):
+    class StatusColumn(SqlTableColumn):
         def get_title(self, session, object):
             return "Status"
 

Modified: mgmt/cumin/python/cumin/client.strings
===================================================================
--- mgmt/cumin/python/cumin/client.strings	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/client.strings	2008-01-08 05:19:48 UTC (rev 1540)
@@ -1,7 +1,5 @@
 [ClientSet.html]
 <form>
-  <div class="rfloat">{page}</div>
-
   {unit}
 
   <div class="sactions">
@@ -13,20 +11,17 @@
   <table class="mobjects">
     <thead>
       <tr>
-        <th></th>
-        {headers}
+        <th class="setnav" colspan="0">
+          <div class="rfloat">{page}</div>
+          {count}
+        </th>
       </tr>
+      <tr>{headers}</tr>
     </thead>
     <tbody>{items}</tbody>
   </table>
 </form>
 
-[ClientSet.item_html]
-<tr>
-  <td><input type="checkbox"/></td>
-  {cells}
-</tr>
-
 [ClientStatus.javascript]
 function updateClientStatus(id, client) {
     updateStatus(id, client);
@@ -135,8 +130,6 @@
 <div class="iblock chart">{received}</div>
 
 [ClientSessionSet.html]
-<div class="rfloat">{page}</div>
-
 <div class="sactions">
   <h2>Act on Selected Sessions:</h2>
   <button>Solicit Ack</button>
@@ -148,16 +141,12 @@
 <table class="mobjects">
   <thead>
     <tr>
-      <th><input type="checkbox"/></th>
-      {headers}
+      <th class="setnav" colspan="0">
+        <div class="rfloat">{page}</div>
+        {count}
+      </th>
     </tr>
+    <tr>{headers}</tr>
   </thead>
-
   <tbody>{items}</tbody>
 </table>
-
-[ClientSessionSet.item_html]
-<tr>
-  <td><input type="checkbox"/></td>
-  {cells}
-</tr>

Modified: mgmt/cumin/python/cumin/exchange.py
===================================================================
--- mgmt/cumin/python/cumin/exchange.py	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/exchange.py	2008-01-08 05:19:48 UTC (rev 1540)
@@ -32,73 +32,131 @@
     def render_item_checked_attr(self, session, exchange):
         return exchange is self.param.get(session) and "checked=\"checked\""
 
-class ExchangeSet(ItemSet):
+class ExchangeSet(CuminTable):
     def __init__(self, app, name):
         super(ExchangeSet, self).__init__(app, name)
 
+        self.table_sql = "exchange as e"
+        self.where_sql = "where e.vhost_id = %(id)r"
+
+        self.add_sql_join("exchange_stats as c", "c.id", "e.stats_curr_id")
+        self.add_sql_join("exchange_stats as p", "p.id", "e.stats_prev_id")
+
+        self.add_sql_column("id", "e.id")
+        self.add_sql_column("name", "e.name")
+        self.add_sql_column("producers", "c.producers")
+        self.add_sql_column("bindings", "c.bindings")
+        self.add_sql_column("mreceived",
+                            "(c.msg_receives - p.msg_receives)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("breceived",
+                            "(c.byte_receives - p.byte_receives)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("mrouted",
+                            "(c.msg_routes - p.msg_routes)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("brouted",
+                            "(c.byte_routes - p.byte_routes)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("mdropped", "c.msg_drops");
+        self.add_sql_column("bdropped", "c.byte_drops");
+
+        col = self.NameColumn(app, "name")
+        self.add_column(col)
+
+        col = self.ProducersColumn(app, "name")
+        self.add_column(col)
+
+        col = self.BindingsColumn(app, "bindings")
+        self.add_column(col)
+
+        col = self.ReceivedColumn(app, "received")
+        self.add_column(col)
+
+        col = self.RoutedColumn(app, "routed")
+        self.add_column(col)
+
+        col = self.DroppedColumn(app, "dropped")
+        self.add_column(col)
+
         self.unit = UnitSwitch(app, "unit")
         self.add_child(self.unit)
-    
-        self.paginator = Paginator(app, "page")
-        self.add_child(self.paginator)
 
     def get_title(self, session, vhost):
         return "Exchanges %s" % fmt_count(self.get_item_count(session, vhost))
 
-    def do_process(self, session, vhost):
-        self.paginator.set_count(session, self.get_item_count(session, vhost))
-
-    def render_unit_plural(self, session, vhost):
+    def get_unit_plural(self, session):
         return self.unit.get(session) == "b" and "Bytes" or "Msgs."
 
     def get_item_count(self, session, vhost):
         return vhost.exchanges.count()
 
-    def do_get_items(self, session, vhost):
-        if vhost:
-            start, end = self.paginator.get_bounds(session)
-            return vhost.exchanges.orderBy("name")[start:end]
+    def get_sql_values(self, session, vhost):
+        return {"id": vhost.id}
 
-    def render_item_link(self, session, exchange):
-        branch = session.branch()
-        self.page().show_exchange(branch, exchange).show_view(branch)
-        name = exchange.name or "<em>Default</em>"
-        return fmt_olink(branch, exchange, name=name)
+    class NameColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Name"
 
-    def render_item_producers(self, session, exchange):
-        branch = session.branch()
-        frame = self.page().show_exchange(branch, exchange)
-        frame.show_view(branch).show_producers(branch)
-        stat = self.app.model.exchange.get_stat("producers")
-        return fmt_link(branch.marshal(), stat.value(exchange))
+        def render_content(self, session, data):
+            exchange = Identifiable(data["id"])
+            branch = session.branch()
+            self.frame().show_exchange(branch, exchange).show_view(branch)
+            name = data["name"] or "<em>Default</em>"
+            return fmt_olink(branch, exchange, name=name)
 
-    def render_item_bindings(self, session, exchange):
-        branch = session.branch()
-        frame = self.page().show_exchange(branch, exchange)
-        frame.show_view(branch).show_bindings(branch)
-        stat = self.app.model.exchange.get_stat("bindings")
-        return fmt_link(branch.marshal(), stat.value(exchange))
+    class ProducersColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Producers"
 
-    def render_item_received(self, session, exchange):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteReceives" or "msgReceives"
-        value = self.app.model.exchange.get_stat(key).rate(exchange)
-        return fmt_rate(value, unit == "b" and "byte" or "msg", "sec")
+        def render_content(self, session, data):
+            exchange = Identifiable(data["id"])
+            branch = session.branch()
+            frame = self.frame().show_exchange(branch, exchange)
+            frame.show_view(branch).show_producers(branch)
+            return fmt_link(branch.marshal(), data["producers"])
 
-    def render_item_routed(self, session, exchange):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteRoutes" or "msgRoutes"
-        value = self.app.model.exchange.get_stat(key).rate(exchange)
-        return fmt_rate(value, unit == "b" and "byte" or "msg", "sec")
+    class BindingsColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Bindings"
 
-    def render_item_dropped(self, session, exchange):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteDrops" or "msgDrops"
-        return self.app.model.exchange.get_stat(key).value(exchange)
+        def render_content(self, session, data):
+            exchange = Identifiable(data["id"])
+            branch = session.branch()
+            frame = self.frame().show_exchange(branch, exchange)
+            frame.show_view(branch).show_bindings(branch)
+            return fmt_link(branch.marshal(), data["bindings"])
 
-    def render_item_status(self, session, exchange):
-        return fmt_ostatus(exchange)
+    class ReceivedColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Received" % self.parent.get_unit_plural(session)
 
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "breceived" or "mreceived"
+
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
+
+    class RoutedColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Routed" % self.parent.get_unit_plural(session)
+
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "brouted" or "mrouted"
+
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
+
+    class DroppedColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Dropped" % self.parent.get_unit_plural(session)
+
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "bdropped" or "mdropped"
+
 def show_producers(page, session, exchange):
     frame = page.show_exchange(session, exchange).show_view(session)
     return frame.show_producers(session)

Modified: mgmt/cumin/python/cumin/exchange.strings
===================================================================
--- mgmt/cumin/python/cumin/exchange.strings	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/exchange.strings	2008-01-08 05:19:48 UTC (rev 1540)
@@ -12,33 +12,23 @@
 }
 
 [ExchangeSet.html]
-<div class="rfloat">{page}</div>
 {unit}
 
 <table class="mobjects">
-  <tr>
-    <th>Name</th>
-    <th class="ralign">Producers</th>
-    <th class="ralign">Queue Bindings</th>
-    <th class="ralign">{unit_plural} Received</th>
-    <th class="ralign">{unit_plural} Routed</th>
-    <th class="ralign">{unit_plural} Dropped</th>
-    <th>Status</th>
-  </tr>
-
-  {items}
+  <thead>
+    <tr>
+      <th class="setnav" colspan="0">
+        <div class="rfloat">{page}</div>
+        {count}
+      </th>
+    </tr>
+    <tr>{headers}</tr>
+  </thead>
+  <tbody>{items}</tbody>
 </table>
 
 [ExchangeSet.item_html]
-<tr>
-  <td>{item_link}</a></td>
-  <td class="ralign">{item_producers}</td>
-  <td class="ralign">{item_bindings}</td>
-  <td class="ralign">{item_received}</td>
-  <td class="ralign">{item_routed}</td>
-  <td class="ralign">{item_dropped}</td>
-  <td>{item_status}</td>
-</tr>
+<tr>{cells}</tr>
 
 [ExchangeForm.html]
 <form id="{id}" class="ExchangeForm mform" method="post" action="?">

Modified: mgmt/cumin/python/cumin/queue.py
===================================================================
--- mgmt/cumin/python/cumin/queue.py	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/queue.py	2008-01-08 05:19:48 UTC (rev 1540)
@@ -3,6 +3,7 @@
 from wooly.widgets import *
 from wooly.forms import *
 from wooly.resources import *
+from wooly.tables import *
 from datetime import datetime
 from sqlobject.sqlbuilder import LEFTJOINOn
 
@@ -15,45 +16,63 @@
 
 strings = StringCatalog(__file__)
 
-class QueueSet(PaginatedItemSet):
+class QueueSet(CuminTable):
     def __init__(self, app, name):
         super(QueueSet, self).__init__(app, name)
 
-        self.unit = UnitSwitch(app, "unit")
-        self.add_child(self.unit)
+        self.table_sql = "queue as q"
+        self.where_sql = "where q.vhost_id = %(id)r"
 
-        self.header = TableHeader(app, "header")
-        self.add_child(self.header)
+        self.add_sql_join("queue_stats as c", "c.id", "q.stats_curr_id")
+        self.add_sql_join("queue_stats as p", "p.id", "q.stats_prev_id")
 
-        col = TableColumn(None)
-        self.header.add_column(col)
+        self.add_sql_column("id", "q.id")
+        self.add_sql_column("name", "q.name")
+        self.add_sql_column("consumers", "c.consumers")
+        self.add_sql_column("bindings", "c.bindings")
+        self.add_sql_column("menqueued",
+                            "(c.msg_total_enqueues - p.msg_total_enqueues)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("benqueued",
+                            "(c.byte_total_enqueues - p.byte_total_enqueues)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("mdequeued",
+                            "(c.msg_total_dequeues - p.msg_total_dequeues)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("bdequeued",
+                            "(c.byte_total_dequeues - p.byte_total_dequeues)" +
+                            " / extract(epoch from (c.rec_time - p.rec_time))");
+        self.add_sql_column("mdepth", "c.msg_depth")
+        self.add_sql_column("bdepth", "c.byte_depth")
+        self.add_sql_column("mdepthaccel", "1")
+        self.add_sql_column("bdepthaccel", "1")
 
-        col = TableColumn("name", Queue.q.name, "Name")
-        self.header.add_column(col)
+        col = CheckboxColumn(app, "id")
+        self.add_column(col)
 
-        col = TableColumn("consumers", QueueStats.q.consumers,
-                          "Consumers", "ralign")
-        self.header.add_column(col)
+        col = self.NameColumn(app, "name")
+        self.add_column(col)
 
-        col = TableColumn("bindings", QueueStats.q.bindings,
-                          "Exchange Bindings", "ralign")
-        self.header.add_column(col)
-        
-        col = self.EnqueuedColumn("enqueued", None, None, "ralign")
-        self.header.add_column(col)
+        self.set_selected_column(col)
 
-        col = self.DequeuedColumn("dequeued", None, None, "ralign")
-        self.header.add_column(col)
+        col = self.ConsumersColumn(app, "consumers")
+        self.add_column(col)
 
-        col = self.DepthColumn("depth", None, None, "ralign")
-        self.header.add_column(col)
+        col = self.BindingsColumn(app, "bindings")
+        self.add_column(col)
 
-        col = TableColumn("accel", None, "Depth Accel.", "ralign")
-        self.header.add_column(col)
+        col = self.EnqueuedColumn(app, "enqueued")
+        self.add_column(col)
 
-        col = TableColumn("status", None, "Status")
-        self.header.add_column(col)
+        col = self.DequeuedColumn(app, "dequeued")
+        self.add_column(col)
 
+        col = self.DepthColumn(app, "depth")
+        self.add_column(col)
+
+        self.unit = UnitSwitch(app, "unit")
+        self.add_child(self.unit)
+
     def get_title(self, session, vhost):
         return "Queues %s" % fmt_count(self.get_item_count(session, vhost))
 
@@ -63,104 +82,74 @@
     def get_unit_plural(self, session):
         return self.unit.get(session) == "b" and "Bytes" or "Msgs."
 
-    class EnqueuedColumn(TableColumn):
-        def get_title(self, session):
-            return "%s Enqueued" % self.header.parent.get_unit_plural \
-                (session)
-
-        def get_data_name(self, session):
-            if self.header.parent.unit.get(session) == "b":
-                return QueueStats.q.byteTotalEnqueues
-            else:
-                return QueueStats.q.msgTotalEnqueues
-
-    class DequeuedColumn(TableColumn):
-        def get_title(self, session):
-            return "%s Dequeued" % self.header.parent.get_unit_plural \
-                (session)
-
-        def get_data_name(self, session):
-            if self.header.parent.unit.get(session) == "b":
-                return QueueStats.q.byteTotalDequeues
-            else:
-                return QueueStats.q.msgTotalDequeues
-
-    class DepthColumn(TableColumn):
-        def get_title(self, session):
-            return "%s Depth" % self.header.parent.get_unit_singular(session)
-
-        def get_data_name(self, session):
-            if self.header.parent.unit.get(session) == "b":
-                return QueueStats.q.byteDepth
-            else:
-                return QueueStats.q.msgDepth
-
     def get_item_count(self, session, vhost):
         return vhost.queues.count()
 
-    def do_get_items(self, session, vhost):
-        if vhost:
-            queues = vhost.queues
-            queues = queues.filter(Queue.q.statsCurrID == QueueStats.q.id)
+    def get_sql_values(self, session, vhost):
+        return {"id": vhost.id}
 
-            column = self.header.get_selected_column(session)
-            queues = column.get_sorted_items(session, queues)
+    class NameColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Name"
 
-            start, end = self.get_bounds(session)
-            queues = queues[start:end]
+        def render_content(self, session, data):
+            queue = Identifiable(data["id"])
+            branch = session.branch()
+            self.frame().show_queue(branch, queue).show_view(branch)
+            return fmt_olink(branch, queue, name=data["name"])
 
-            if self.header.is_reversed(session):
-                queues = queues.reversed()
+    class ConsumersColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Consumers"
 
-            return queues
+        def render_content(self, session, data):
+            queue = Identifiable(data["id"])
+            branch = session.branch()
+            frame = self.frame().show_queue(branch, queue)
+            frame.show_view(branch).show_consumers(branch)
+            return fmt_link(branch.marshal(), data["consumers"])
 
-    def render_item_link(self, session, queue):
-        branch = session.branch()
-        self.page().show_queue(branch, queue).show_view(branch)
-        return fmt_olink(branch, queue)
+    class BindingsColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "Bindings"
 
-    def render_item_name(self, session, queue):
-        return queue.name
+        def render_content(self, session, data):
+            queue = Identifiable(data["id"])
+            branch = session.branch()
+            frame = self.frame().show_queue(branch, queue)
+            frame.show_view(branch).show_bindings(branch)
+            return fmt_link(branch.marshal(), data["bindings"])
 
-    def render_item_consumers(self, session, queue):
-        branch = session.branch()
-        frame = self.page().show_queue(branch, queue)
-        frame.show_view(branch).show_consumers(branch)
-        stat = self.app.model.queue.get_stat("consumers")
-        return fmt_link(branch.marshal(), stat.value(queue))
+    class EnqueuedColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Enqueued" % self.parent.get_unit_plural(session)
 
-    def render_item_bindings(self, session, queue):
-        branch = session.branch()
-        frame = self.page().show_queue(branch, queue)
-        frame.show_view(branch).show_bindings(branch)
-        stat = self.app.model.queue.get_stat("bindings")
-        return fmt_link(branch.marshal(), stat.value(queue))
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "benqueued" or "menqueued"
 
-    def render_item_enqueued(self, session, queue):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteTotalEnqueues" or "msgTotalEnqueues"
-        value = self.app.model.queue.get_stat(key).rate(queue)
-        return fmt_rate(value, unit == "b" and "byte" or "msg", "sec")
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
 
-    def render_item_dequeued(self, session, queue):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteTotalDequeues" or "msgTotalDequeues"
-        value = self.app.model.queue.get_stat(key).rate(queue)
-        return fmt_rate(value, unit == "b" and "byte" or "msg", "sec")
+    class DequeuedColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Dequeued" % self.parent.get_unit_plural(session)
 
-    def render_item_depth(self, session, queue):
-        key = self.unit.get(session) == "b" and "byteDepth" or "msgDepth"
-        return self.app.model.queue.get_stat(key).value(queue)
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "bdequeued" or "mdequeued"
 
-    def render_item_depth_accel(self, session, queue):
-        unit = self.unit.get(session)
-        key = unit == "b" and "byteDepth" or "msgDepth"
-        value = self.app.model.queue.get_stat(key).rate(queue)
-        return fmt_rate(value, unit == "b" and "byte" or "msg", "sec")
+        def render_value(self, session, value):
+            return fmt_rate(value, "", "sec")
 
-    def render_item_status(self, session, queue):
-        return fmt_ostatus(queue)
+    class DepthColumn(SqlTableColumn):
+        def get_title(self, session, object):
+            return "%s Depth" % self.parent.get_unit_singular(session)
 
+        def get_column_key(self, session):
+            unit = self.parent.unit.get(session)
+            return unit == "b" and "bdepth" or "mdepth"
+
 def show_consumers(page, session, queue):
     frame = page.show_queue(session, queue).show_view(session)
     return frame.show_consumers(session)

Modified: mgmt/cumin/python/cumin/queue.strings
===================================================================
--- mgmt/cumin/python/cumin/queue.strings	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/queue.strings	2008-01-08 05:19:48 UTC (rev 1540)
@@ -1,13 +1,5 @@
-[QueueSet.css]
-ul.QueueSet li:before {
-  content: url(resource?name=queue-20.png);
-  vertical-align: -30%;
-  padding: 0 0.25em;
-}
-
 [QueueSet.html]
-<!-- <form action="{href}" method="get"> -->
-  <div class="rfloat">{page}</div>
+<form>
   {unit}
 
   <div class="sactions">
@@ -16,24 +8,19 @@
   </div>
 
   <table class="mobjects">
-    {header}
-    {items}
+    <thead>
+      <tr>
+        <th class="setnav" colspan="0">
+          <div class="rfloat">{page}</div>
+          {count}
+        </th>
+      </tr>
+      <tr>{headers}</tr>
+    </thead>
+    <tbody>{items}</tbody>
   </table>
-<!-- </form> -->
+</form>
 
-[QueueSet.item_html]
-<tr>
-  <td><input type="checkbox"/></td>
-  <td>{item_link}</a></td>
-  <td class="ralign">{item_consumers}</td>
-  <td class="ralign">{item_bindings}</td>
-  <td class="ralign">{item_enqueued}</td>
-  <td class="ralign">{item_dequeued}</td>
-  <td class="ralign">{item_depth}</td>
-  <td class="ralign">{item_depth_accel}</td>
-  <td>{item_status}</td>
-</tr>
-
 [QueueForm.html]
 <form id="{id}" class="mform" method="post" action="?">
   <div class="head">

Modified: mgmt/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/cumin/python/cumin/widgets.py	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/widgets.py	2008-01-08 05:19:48 UTC (rev 1540)
@@ -374,7 +374,7 @@
 
     def get_limit_sql(self, session):
         start, end = self.paginator.get_bounds(session)
-        return "limit %i offset %i" % (end, start)
+        return "limit %i offset %i" % (end - start, start)
 
 class PaginatedItemSet(ItemSet):
     def __init__(self, app, name):

Modified: mgmt/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/cumin/python/cumin/widgets.strings	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/cumin/widgets.strings	2008-01-08 05:19:48 UTC (rev 1540)
@@ -88,10 +88,6 @@
 <li>{item_link}</li>
 
 [Paginator.css]
-div.Paginator {
-  margin: 0 0 0.5em 0;
-}
-
 div.Paginator ul {
   display: inline;
 }
@@ -108,6 +104,20 @@
 [Paginator.item_html]
 <li><a {item_class_attr} href="{item_href}">{item_content}</a></li>
 
+[CuminTable.html]
+<table class="mobjects">
+  <thead>
+    <tr>
+      <th class="setnav" colspan="0">
+        <div class="rfloat">{page}</div>
+        {count}
+      </th>
+    </tr>
+    <tr>{headers}</tr>
+  </thead>
+  <tbody>{items}</tbody>
+</table>
+
 [TableHeader.css]
 th.selected a {
   color: black;

Modified: mgmt/cumin/python/wooly/tables.py
===================================================================
--- mgmt/cumin/python/wooly/tables.py	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/wooly/tables.py	2008-01-08 05:19:48 UTC (rev 1540)
@@ -17,7 +17,7 @@
         self.add_parameter(self.scolumn)
 
         self.reversed = BooleanParameter(app, "rev")
-        self.reversed.set_default(False)
+        self.reversed.default = False
         self.add_parameter(self.reversed)
 
     def add_column(self, column):
@@ -33,6 +33,9 @@
             if column.name == name:
                 return column
 
+    def set_selected_column(self, column):
+        self.scolumn.default = column.name
+
     def is_reversed(self, session):
         return self.reversed.get(session)
 
@@ -41,6 +44,10 @@
 
         return None
 
+    def render_count(self, session, object):
+        count = self.get_item_count(session, object)
+        return "%i %s" % (count, count == 1 and "item" or "items")
+
     def render_headers(self, session, object):
         writer = Writer()
 
@@ -89,9 +96,19 @@
     def __init__(self, app, name):
         super(ItemTableColumn, self).__init__(app, name)
 
+    def get_column_key(self, session):
+        return self.name
+
     def do_render(self, session, data):
-        return "<td>%s</td>" % str(data[self.name])
+        return "<td>%s</td>" % self.render_content(session, data)
 
+    def render_content(self, session, data):
+        key = self.get_column_key(session)
+        return self.render_value(session, data[key])
+
+    def render_value(self, session, value):
+        return str(value)
+
 class SqlTable(ItemTable):
     def __init__(self, app, name):
         super(SqlTable, self).__init__(app, name)
@@ -141,15 +158,9 @@
 
     def get_orderby_sql(self, session):
         scol = self.get_selected_column(session)
-        sqlcol = self.get_sql_column(scol.name)
 
-        if sqlcol:
-            column_sql = sqlcol.get_sql(session)
-            dir = self.is_reversed(session) and "desc" or "asc"
-            sql = "order by %s %s" % (column_sql, dir)
+        return scol.get_orderby_sql(session)
 
-            return sql
-
     def get_limit_sql(self, session):
         return None
 
@@ -169,8 +180,6 @@
 
         sql = writer.to_string()
 
-        #print sql
-
         return sql
 
     def get_sql_values(self, session, object):
@@ -179,6 +188,7 @@
     def get_connection(self, session):
         pass
 
+    # XXX shouldn't this be do_get_items?
     def get_items(self, session, object):
         conn = self.get_connection(session)
 
@@ -187,23 +197,17 @@
             sql = self.get_sql(session)
             sql_values = self.get_sql_values(session, object)
 
+            #print "SQL TEXT", sql
+            #print "SQL VALS", sql_values
+
             cursor.execute(sql, sql_values)
 
             return cursor
 
-    def do_render(self, session, object):
+    def render_items(self, session, object):
+        writer = Writer()
         cursor = self.get_items(session, object)
 
-        if cursor:
-            html = super(ItemSet, self).do_render(session, cursor)
-        else:
-            html = self.render_none(session, object)
-
-        return html
-
-    def render_items(self, session, cursor):
-        writer = Writer()
-
         for row in cursor:
             self.item_tmpl.render(session, row, writer)
 
@@ -229,7 +233,7 @@
             self.sql = sql
 
         def get_sql(self, session):
-            return self.sql
+            return "%s as %s" % (self.sql, self.name)
 
     class SqlJoin(object):
         def __init__(self, table,
@@ -259,3 +263,16 @@
                      "=", self.get_fk_column_sql(session))
 
             return " ".join(elems)
+
+class SqlTableColumn(ItemTableColumn):
+    def get_orderby_sql(self, session):
+        key = self.get_column_key(session)
+
+        if key:
+            dir = self.parent.is_reversed(session) and "desc" or "asc"
+            return "order by %s %s" % (key, dir)
+
+class CheckboxColumn(ItemTableColumn):
+    def do_render(self, session, data):
+        return "<td><input type=\"checkbox\" name=\"%s\"/></td>" % \
+            data[self.name]

Modified: mgmt/cumin/python/wooly/tables.strings
===================================================================
--- mgmt/cumin/python/wooly/tables.strings	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/cumin/python/wooly/tables.strings	2008-01-08 05:19:48 UTC (rev 1540)
@@ -1,6 +1,6 @@
 [ItemTable.html]
 <table>
-  <thead>{headers}</thead>
+  <thead><tr>{headers}</tr></thead>
   <tbody>{items}</tbody>
 </table>
 
@@ -8,6 +8,4 @@
 <th class="{header_class}"><a href="{header_href}">{header_content}</a></th>
 
 [ItemTable.item_html]
-<tr>
-  {cells}
-</tr>
+<tr>{cells}</tr>

Modified: mgmt/notes/justin-todo.txt
===================================================================
--- mgmt/notes/justin-todo.txt	2008-01-07 21:37:50 UTC (rev 1539)
+++ mgmt/notes/justin-todo.txt	2008-01-08 05:19:48 UTC (rev 1540)
@@ -12,16 +12,8 @@
 
    - Display current values on right-side and according to color
 
-   - Add y-axis ticks and values for reference
-
    - Add a "rate" mode to charts
 
- * Sortify brokers
-
- * Sortify clients
-
- * Sortify sessions
-
  * Mgmtd-broker interaction
 
    - Deal with problem of calling method on broker that is not there
@@ -30,13 +22,26 @@
 
    - Handle other exception conditions on broker connect more gracefully
 
- * Add "slowest views" tracking to --bench
+ * Tables
 
+   - Indicate selected (sorted-by) column
+
+   - Add sort direction icon
+
+   - Deal with large numbers of pages in paginators
+
+   - Change first-click sort to desc for number fields
+
+ * Div by zero error in queues view
+
 Deferred
 
- * Prevent browsers from caching the chart pngs and then running out
-   of memory
+ * Add "slowest views" tracking to --bench
 
+ * Get rid of SQLObjectItemSet
+
+ * Sortify brokers
+
  * Only perform js updates if there's new data
 
  * Avoid dirtying js namespace with updateFoo methods
@@ -46,12 +51,6 @@
  * Directly set attr.default for static defaults; eliminate
    attr.set_default
 
- * Add sort direction icon
-
- * Deal with large numbers of pages in paginators
-
- * Change first-click sort to desc for number fields
-
  * Rename BrokerAdd on CuminPage to BrokerSetAdd
 
  * So that list params can embed an item param, find a way to avoid
@@ -61,8 +60,6 @@
 
  * Sortify broker groups
 
- * Sortify exchanges
-
  * Broker groups
 
    - Group form submit has different behaviors between hitting enter
@@ -70,12 +67,8 @@
 
  * Add [None] to groups field in broker view
 
- * Go back to Widget.parent as an attr, not a function
-
  * Indicate how old stats are
 
- * Need way to control connectToBroker timeout
-
  * Add broker reg name unique constraint and validation
 
  * Whereever it makes sense, add a switch to display living, dead, or
@@ -92,8 +85,6 @@
 
  * Paginate consumers
 
- * Paginate sessions
-
  * Email amqp-list, Jonathan, and Lana with doc requirements for mgmt
 
  * Ask tross to take some prints out of ManagedBroker.start
@@ -165,5 +156,3 @@
 
  * Add a sanity check traversal to the widget tree and to the
    registered sets of widgets and parameters
-
- * Add a frame() accessor to Widget




More information about the rhmessaging-commits mailing list