[rhmessaging-commits] rhmessaging commits: r3912 - in mgmt/newdata: cumin/python/cumin/account and 4 other directories.

rhmessaging-commits at lists.jboss.org rhmessaging-commits at lists.jboss.org
Wed Apr 14 13:35:03 EDT 2010


Author: justi9
Date: 2010-04-14 13:34:58 -0400 (Wed, 14 Apr 2010)
New Revision: 3912

Added:
   mgmt/newdata/cumin/python/cumin/grid/daemon.py
Removed:
   mgmt/newdata/cumin/python/cumin/action.py
   mgmt/newdata/cumin/python/cumin/messaging/model.py
   mgmt/newdata/cumin/python/cumin/table.py
   mgmt/newdata/cumin/python/cumin/table.strings
Modified:
   mgmt/newdata/cumin/python/cumin/account/main.py
   mgmt/newdata/cumin/python/cumin/account/widgets.py
   mgmt/newdata/cumin/python/cumin/grid/collector.py
   mgmt/newdata/cumin/python/cumin/grid/collector.strings
   mgmt/newdata/cumin/python/cumin/grid/job.strings
   mgmt/newdata/cumin/python/cumin/grid/limit.py
   mgmt/newdata/cumin/python/cumin/grid/main.py
   mgmt/newdata/cumin/python/cumin/grid/model.py
   mgmt/newdata/cumin/python/cumin/grid/negotiator.py
   mgmt/newdata/cumin/python/cumin/grid/negotiator.strings
   mgmt/newdata/cumin/python/cumin/grid/pool.py
   mgmt/newdata/cumin/python/cumin/grid/scheduler.py
   mgmt/newdata/cumin/python/cumin/grid/scheduler.strings
   mgmt/newdata/cumin/python/cumin/grid/submission.py
   mgmt/newdata/cumin/python/cumin/grid/submission.strings
   mgmt/newdata/cumin/python/cumin/grid/submitter.py
   mgmt/newdata/cumin/python/cumin/grid/submitter.strings
   mgmt/newdata/cumin/python/cumin/main.py
   mgmt/newdata/cumin/python/cumin/messaging/binding.py
   mgmt/newdata/cumin/python/cumin/messaging/broker.py
   mgmt/newdata/cumin/python/cumin/messaging/brokergroup.py
   mgmt/newdata/cumin/python/cumin/messaging/brokerlink.py
   mgmt/newdata/cumin/python/cumin/messaging/connection.py
   mgmt/newdata/cumin/python/cumin/messaging/connection.strings
   mgmt/newdata/cumin/python/cumin/messaging/exchange.py
   mgmt/newdata/cumin/python/cumin/messaging/main.py
   mgmt/newdata/cumin/python/cumin/messaging/queue.py
   mgmt/newdata/cumin/python/cumin/model.py
   mgmt/newdata/cumin/python/cumin/objectframe.py
   mgmt/newdata/cumin/python/cumin/objectframe.strings
   mgmt/newdata/cumin/python/cumin/objectselector.py
   mgmt/newdata/cumin/python/cumin/objectselector.strings
   mgmt/newdata/cumin/python/cumin/objecttask.py
   mgmt/newdata/cumin/python/cumin/parameters.py
   mgmt/newdata/cumin/python/cumin/sqladapter.py
   mgmt/newdata/cumin/python/cumin/widgets.py
   mgmt/newdata/misc/boneyard.py
   mgmt/newdata/wooly/python/wooly/datatable.py
   mgmt/newdata/wooly/python/wooly/table.py
Log:
 * Tasks part 2; just a little more work remains here

 * Provide a (read only) cursor on session

 * Removed a lot of obsoleted Frame and View classes


Modified: mgmt/newdata/cumin/python/cumin/account/main.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/account/main.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/account/main.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -8,9 +8,9 @@
     def __init__(self, app, name):
         super(Module, self).__init__(app, name)
         
-        cls = app.rosemary.com_redhat_cumin.User
+        #cls = app.rosemary.com_redhat_cumin.User
 
-        ChangePassword(self, cls)
+        #ChangePassword(self, cls)
 
         self.app.login_page = LoginPage(self.app, "login.html")
         self.app.add_page(self.app.login_page)

Modified: mgmt/newdata/cumin/python/cumin/account/widgets.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/account/widgets.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/account/widgets.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -47,9 +47,9 @@
 class SettingsView(Widget):
     def init(self):
         # XXX deferring this, but I don't like it
-        task = self.app.account.ChangePassword
-        link = ObjectTaskLink(self.app, "change_password", task, None)
-        self.add_child(link)
+        #task = self.app.account.ChangePassword
+        #link = ObjectTaskLink(self.app, "change_password", task, None)
+        #self.add_child(link)
 
         super(SettingsView, self).init()
 
@@ -111,19 +111,12 @@
 
             if not self.errors.get(session):
                 cls = self.app.rosemary.com_redhat_cumin.User
-                name_literal = "'%s'" % name
                 user = None
             
-                conn = self.app.model.get_sql_connection()
-                cursor = conn.cursor()
+                for obj in cls.get_selection(session.cursor, name=name):
+                    user = obj
+                    break
 
-                try:
-                    for obj in cls.get_selection(cursor, name=name_literal):
-                        user = obj
-                        break
-                finally:
-                    cursor.close()
-
                 if not user:
                     self.login_invalid.set(session, True)
                     return
@@ -203,7 +196,7 @@
             password = self.new0.get(session)
 
             self.task.invoke(session, user, password)
-            self.task.exit_with_redirect(session, user)
+            self.task.exit_with_redirect(session)
 
     class Current(PasswordField):
         def render_title(self, session):

Deleted: mgmt/newdata/cumin/python/cumin/action.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/action.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/action.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,62 +0,0 @@
-from wooly import *
-from wooly.pages import *
-from wooly.tables import *
-from datetime import datetime
-
-from util import *
-from formats import *
-
-strings = StringCatalog(__file__)
-
-class ActionInvocationSet(ItemSet):
-    def __init__(self, app, name):
-        super(ActionInvocationSet, self).__init__(app, name)
-
-        self.update_enabled = True
-
-    def get_item_count(self, session, *args):
-        items = self.do_get_items(session, *args)
-        return len(items)
-
-    def do_get_items(self, session, *args):
-        nsecs = secs(datetime.now())
-        return [x for x in reversed(sorted_by(self.app.model.invocations, "when")) if nsecs - secs(x.when) < 60]
-
-    def render_item_content(self, session, item):
-        delta = secs(datetime.now()) - secs(item.when)
-        if delta < 60:
-            return super(ActionInvocationSet, self).render_item_content(session, item)
-
-    def render_when(self, session, item):
-        delta = secs(datetime.now()) - secs(item.when)
-        duration = fmt_duration(delta)
-        if duration:
-            return "%s ago" % duration
-        else:
-            return ""
-
-    def render_description(self, session, item):
-        return item.get_description(session)
-
-    def render_status_class(self, session, item):
-        text = "normal"
-        if item.status == "pending":
-            text = "warning"
-        else:
-            if item.exception:
-                text = "error"
-
-        return text
-
-    def render_status(self, session, item):
-        if item.status == "pending":
-            text = "Pending"
-        elif item.status == "OK":
-            text = "Completed"
-        else:
-            if item.exception:
-                text = "Failed: " + str(item.exception)
-            else:
-                text = "Failed: " + item.status
-
-        return text

Modified: mgmt/newdata/cumin/python/cumin/grid/collector.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/collector.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/collector.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -5,6 +5,9 @@
 from wooly.forms import *
 from wooly.resources import *
 from wooly.tables import *
+
+from cumin.objectframe import *
+from cumin.objecttask import *
 from cumin.stat import *
 from cumin.widgets import *
 from cumin.parameters import *
@@ -16,72 +19,24 @@
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.grid.collector")
 
-class CollectorSet(CuminSelectionTable):
+class CollectorFrame(ObjectFrame):
     def __init__(self, app, name):
-        item = CollectorParameter(app, "item")
-        super(CollectorSet, self).__init__(app, name, item)
+        cls = app.rosemary.mrg_grid.Collector
 
-        col = self.NameColumn(app, "name")
-        self.add_column(col)
-        self.set_default_column(col)
+        super(CollectorFrame, self).__init__(app, name, cls)
 
-        col = self.SystemColumn(app, "system")
-        self.add_column(col)
+        self.view.add_tab(CollectorOverview(app, "stats", self.object))
 
-        task = main.module.collector_set_start
-        button = TaskButton(app, "start", task, self.selection)
-        self.buttons.add_child(button)
+        self.start = DaemonStart(app, self, "COLLECTOR")
+        self.stop = DaemonStop(app, self, "COLLECTOR")
 
-        task = main.module.collector_set_stop
-        button = TaskButton(app, "stop", task, self.selection)
-        self.buttons.add_child(button)
-
-    def render_title(self, session):
-        count = self.get_item_count(session)
-        return "Collectors %s" % fmt_count(count)
-
-    def render_sql_where(self, session):
-        sql = "qmf_delete_time is null"
-        return "where %s" % sql
-
-    class NameColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Name"
-
-        def render_content(self, session, data):
-            coll = Identifiable(data["id"])
-            href = self.page.main.grid.pool.collector.get_href(session, coll)
-            return fmt_link(href, data["name"])
-
-    class SystemColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "System"
-
-        def render_content(self, session, data):
-            id = data["system_id"]
-
-            if id:
-                sys = Identifiable(id)
-                href = self.page.main.inventory.system.get_href(session, sys)
-                return fmt_link(href, data["system_name"])
-
-class CollectorFrame(CuminFrame):
-    def __init__(self, app, name):
-        super(CollectorFrame, self).__init__(app, name)
-
-        self.object = CollectorParameter(app, "id")
-        self.add_parameter(self.object)
-
-        self.view = CollectorView(app, "view", self.object)
-        self.add_mode(self.view)
-
 class CollectorGeneralStatSet(StatSet):
     def __init__(self, app, name, object):
         super(CollectorGeneralStatSet, self).__init__(app, name, object)
 
         self.attrs = ("RunningJobs", "IdleJobs",
-                "HostsClaimed", "HostsUnclaimed",
-                "HostsOwner", "HostsTotal")
+                      "HostsClaimed", "HostsUnclaimed",
+                      "HostsOwner", "HostsTotal")
 
 class CollectorOverview(Widget):
     def __init__(self, app, name, collector):
@@ -100,7 +55,7 @@
         self.add_child(chart)
 
     def render_title(self, session):
-        return "Statistics"
+        return "Overview"
 
     class JobStackedChart(StatFlashChart):
         def render_title(self, session):
@@ -109,36 +64,3 @@
     class SlotStackedChart(StatFlashChart):
         def render_title(self, session, *args):
             return "Slot state"
-
-class CollectorView(CuminView):
-    def __init__(self, app, name, collector):
-        super(CollectorView, self).__init__(app, name, collector)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        self.tabs.add_tab(CollectorOverview(app, "stats", collector))
-        self.tabs.add_tab(CuminDetails(app, "details", collector))
-
-class CollectorStartForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(CollectorStartForm, self).__init__(app, name, task)
-
-        self.object = CollectorParameter(app, "collector")
-        self.add_parameter(self.object)
-
-class CollectorStopForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(CollectorStopForm, self).__init__(app, name, task)
-
-        self.object = CollectorParameter(app, "collector")
-        self.add_parameter(self.object)
-
-class CollectorSetTaskForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(CollectorSetTaskForm, self).__init__(app, name, task)
-
-        item = CollectorParameter(app, "item")
-
-        self.object = ListParameter(app, "collector", item)
-        self.add_parameter(self.object)

Modified: mgmt/newdata/cumin/python/cumin/grid/collector.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/collector.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/collector.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,21 +1,3 @@
-[CollectorSet.sql]
-select
-  c.id,
-  c.name,
-  y.id as system_id,
-  y.node_name as system_name
-from collector as c
-left outer join sysimage as y on c.system = y.node_name
-left outer join collector_stats as cs on cs.id = c.stats_curr_id
-{sql_where}
-{sql_orderby}
-{sql_limit}
-
-[CollectorSet.count_sql]
-select count(1) from collector as c
-left outer join collector_stats as cs on cs.id = c.stats_curr_id
-{sql_where}
-
 [CollectorOverview.html]
 <table class="twocol">
   <tbody>

Added: mgmt/newdata/cumin/python/cumin/grid/daemon.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/daemon.py	                        (rev 0)
+++ mgmt/newdata/cumin/python/cumin/grid/daemon.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -0,0 +1,85 @@
+from cumin.objecttask import *
+
+class DaemonStart(ObjectTask):
+    def __init__(self, app, frame, target):
+        super(DaemonStart, self).__init__(app, frame)
+
+        self.target = target
+
+        self.name = "%s_%s" % (self.name, self.target)
+
+    def get_title(self, session):
+        return "Start"
+
+    def do_invoke(self, invoc, daemon):
+        system_name = daemon.System
+
+        try:
+            master = Master.select("System = '%s'" % system_name)[0]
+        except IndexError:
+            raise Exception("Master daemon not running")
+
+        master.Start(completion, self.target)
+
+class DaemonStop(ObjectTask):
+    def __init__(self, app, frame, target):
+        super(DaemonStop, self).__init__(app, frame)
+
+        self.target = target
+
+        self.name = "%s_%s" % (self.name, self.target)
+
+    def get_title(self, session):
+        return "Stop"
+
+    def do_invoke(self, invoc, daemon):
+        system_name = daemon.System
+
+        try:
+            master = Master.select("System = '%s'" % system_name)[0]
+        except IndexError:
+            raise Exception("Master daemon not running")
+
+        master.Stop(completion, self.target)
+
+class DaemonSelectionStart(SelectionTask):
+    def __init__(self, app, selector, target):
+        super(DaemonSelectionStart, self).__init__(app, selector)
+
+        self.target = target
+
+        self.name = "%s_%s" % (self.name, self.target)
+
+    def get_title(self, session):
+        return "Start"
+
+    def do_invoke(self, invoc, daemon):
+        system_name = daemon.System
+
+        try:
+            master = Master.select("System = '%s'" % system_name)[0]
+        except IndexError:
+            raise Exception("Master daemon not running")
+
+        master.Start(completion, self.target)
+
+class DaemonSelectionStop(SelectionTask):
+    def __init__(self, app, selector, target):
+        super(DaemonSelectionStop, self).__init__(app, selector)
+
+        self.target = target
+
+        self.name = "%s_%s" % (self.name, self.target)
+
+    def get_title(self, session):
+        return "Stop"
+
+    def do_invoke(self, invoc, daemon):
+        system_name = daemon.System
+
+        try:
+            master = Master.select("System = '%s'" % system_name)[0]
+        except IndexError:
+            raise Exception("Master daemon not running")
+
+        master.Stop(completion, self.target)

Modified: mgmt/newdata/cumin/python/cumin/grid/job.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/job.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/job.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,45 +1,3 @@
-[JobSet.sql]
-select
-  j.id,
-  j.accounting_group as agroup,
-  j.args,
-  j.cluster_id,
-  j.concurrency_limits,
-  j.custom_group,
-  j.custom_id,
-  j.custom_priority,
-  j.job_status,
-  j.title,
-  s.name as scheduler,
-  b.name as submitter,
-  j.scheduler_id,
-  j.submitter_id,
-  j.cmd,
-  j.qmf_delete_time
-from job as j
-{stats_join}
-inner join scheduler as s on s.id = j.scheduler_id
-inner join submitter as b on b.id = j.submitter_id
-{sql_where}
-{sql_orderby}
-{sql_limit}
-
-[JobSet.find_sql]
-select
-        j.id,
-        j.custom_id
-from job as j
-inner join scheduler as s on s.id = j.scheduler_id
-inner join submitter as b on b.id = j.submitter_id
-
-[JobSet.count_sql]
-select count(1)
-from job as j
-{stats_join}
-inner join scheduler as s on s.id = j.scheduler_id
-inner join submitter as b on b.id = j.submitter_id
-{sql_where}
-
 [JobTab.css]
 input.search_input {
     color: #555;
@@ -57,7 +15,6 @@
     padding-top: 2px;
 }
 
-
 [JobTab.javascript]
 function JobSearchFocus() {
     var val = this.value;

Modified: mgmt/newdata/cumin/python/cumin/grid/limit.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/limit.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/limit.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -148,7 +148,7 @@
 
         if not self.errors.get(session):
             self.task.invoke(session, negotiator, name, max)
-            self.task.exit_with_redirect(session, (negotiator, name))
+            self.task.exit_with_redirect(session)
 
 class LimitView(CuminView):
     def __init__(self, app, name, negotiator, limit):

Modified: mgmt/newdata/cumin/python/cumin/grid/main.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/main.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/main.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -3,6 +3,7 @@
 from wooly.resources import *
 
 from cumin import *
+from cumin.objecttask import *
 from cumin.util import *
 
 from model import *
@@ -15,10 +16,6 @@
     def __init__(self, app, name):
         super(Module, self).__init__(app, name)
 
-        cls = app.rosemary.mrg_grid.Submission
-
-        SubmissionAdd(self, cls)
-
         # cls = app.rosemary.mrg_grid.Job
 
         # JobHold(self, cls)
@@ -26,26 +23,8 @@
         # JobRemove(self, cls)
         # JobSetAttribute(self, cls)
 
-        cls = app.rosemary.mrg_grid.Scheduler
-        
-        start = SchedulerStart(self, cls)
-        stop = SchedulerStop(self, cls)
-
-        SelectionTask(start)
-        SelectionTask(stop)
-
-        cls = app.rosemary.mrg_grid.Collector
-
-        start = CollectorStart(self, cls)
-        stop = CollectorStop(self, cls)
-
-        SelectionTask(start)
-        SelectionTask(stop)
-
         # cls = app.rosemary.mrg_grid.Negotiator
 
-        # NegotiatorStart(self, cls)
-        # NegotiatorStop(self, cls)
         # NegotiatorEditDynamicQuota(self, cls)
         # NegotiatorEditStaticQuota(self, cls)
         # NegotiatorEditPrioFactor(self, cls)

Modified: mgmt/newdata/cumin/python/cumin/grid/model.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/model.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/model.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -19,178 +19,6 @@
 #     def do_enter(self, session, scheduler):
 #         self.app.main_page.grid.view.show(branch)
 
-class SubmissionAdd(ObjectTask):
-    EXPR_TYPE, INTEGER_TYPE, FLOAT_TYPE, STRING_TYPE = 0, 1, 2, 3
-    UNIVERSE = {"VANILLA": 5,
-                "SCHEDULER": 7,
-                "GRID": 9,
-                "JAVA": 10,
-                "PARALLEL": 11,
-                "LOCAL": 12,
-                "VM": 13}
-
-    def __init__(self, module, cls):
-        super(SubmissionAdd, self).__init__(module, cls)
-
-        self.form = SubmissionAddForm(module.app, "submission_add", self)
-
-    def get_title(self, session, scheduler):
-        return "Create submission"
-
-    def do_invoke(self, invoc, scheduler,
-                  description,
-                  executable,
-                  args=None,
-                  iwd="/tmp",
-                  stdin=None,
-                  stdout=None,
-                  stderr=None,
-                  requirements="TRUE",
-                  universe="VANILLA"):
-        user_name = invoc.user.name
-
-        ad = {
-            "Submission":   {"TYPE": self.STRING_TYPE,
-                             "VALUE": condor_string(description)},
-            "Cmd":          {"TYPE": self.STRING_TYPE,
-                             "VALUE": condor_string(executable)},
-            "Args":         {"TYPE": self.STRING_TYPE,
-                             "VALUE": condor_string(args)},
-            "Requirements": {"TYPE": self.EXPR_TYPE,
-                             "VALUE": requirements},
-            "JobUniverse":  {"TYPE": self.INTEGER_TYPE,
-                             "VALUE": str(self.UNIVERSE[universe])},
-            "Iwd":          {"TYPE": self.STRING_TYPE,
-                             "VALUE": condor_string(iwd)},
-            "Owner":        {"TYPE": self.STRING_TYPE,
-                             "VALUE": "guest3"}
-            }
-
-#            "User":         {"TYPE": self.STRING_TYPE,
-#                             "VALUE": condor_string("example at example.com")}
-
-        scheduler.Submit(completion, ad, None)
-
-def condor_string(string):
-    return string
-    # XXX return "\"%s\"" % string
-
-class NegotiatorStart(ObjectTask):
-    def get_title(self, session, negotiator):
-        return "Start"
-
-    def do_invoke(self, invoc, negotiator):
-        system_name = negotiator.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Start(completion, "NEGOTIATOR")
-
-class NegotiatorStop(ObjectTask):
-    def get_title(self, session, negotiator):
-        return "Stop"
-
-    def do_invoke(self, invoc, negotiator):
-        system_name = negotiator.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Stop(completion, "NEGOTIATOR")
-
-class NegotiatorLimitSet(ObjectTask):
-    def __init__(self, module, cls):
-        super(NegotiatorLimitSet, self).__init__(module, cls)
-
-        self.form = NegotiatorLimitSetForm(module.app, self.name, self)
-
-    def do_enter(self, session, limit):
-        self.form.negotiator.set(session, limit[0])
-        self.form.limit_name.set(session, limit[1])
-
-    def get_title(self, session):
-        return "Set limit"
-
-    def do_invoke(self, invoc, negotiator, name, max):
-        assert isinstance(negotiator, Negotiator)
-
-        negotiator.SetLimit(completion, name, max)
-
-        # XXX 
-        def completion():
-            pass
-
-        negotiator.Reconfig(completion)
-        
-class CollectorStart(ObjectTask):
-    def get_title(self, session):
-        return "Start"
-
-    def do_invoke(self, invoc, collector):
-        assert isinstance(collector, Collector)
-
-        system_name = collector.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Start(completion, "COLLECTOR")
-
-class CollectorStop(ObjectTask):
-    def get_title(self, session):
-        return "Stop"
-
-    def do_invoke(self, invoc, collector):
-        assert isinstance(collector, Collector)
-
-        system_name = collector.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Stop(completion, "COLLECTOR")
-
-class SchedulerStart(ObjectTask):
-    def get_title(self, session, scheduler):
-        return "Start"
-
-    def do_invoke(self, invoc, scheduler):
-        assert isinstance(scheduler, Scheduler)
-
-        system_name = scheduler.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Start(completion, "SCHEDD")
-
-class SchedulerStop(ObjectTask):
-    def get_title(self, session, sheduler):
-        return "Stop"
-
-    def do_invoke(self, invoc, scheduler):
-        assert isinstance(scheduler, Scheduler)
-
-        system_name = scheduler.System
-
-        try:
-            master = Master.select("System = '%s'" % system_name)[0]
-        except IndexError:
-            raise Exception("Master daemon not running")
-
-        master.Stop(completion, "SCHEDD")
-
 # class JobBaseTask(QmfTask):
 #     def __init__(self, app, cls, form, verb):
 #         super(JobBaseTask, self).__init__(app, cls)
@@ -283,87 +111,3 @@
 
 #     def get_title(self, session):
 #         return "Set Job Attribute"
-
-class NegotiatorGroupTask(ObjectTask):
-    def do_exit(self, session, negotiator):
-        self.app.main_page.main.grid.pool.negotiator.view.show(session)
-
-    def do_invoke(self, completion, session, negotiator, group, value):
-        assert isinstance(negotiator, Negotiator)
-
-        if group == "Reconfig":
-            negotiator.Reconfig(completion)
-        else:
-            negotiator.SetRawConfig(completion, group, value)
-
-class NegotiatorAddGroup(NegotiatorGroupTask):
-    def __init__(self, module, cls):
-        super(NegotiatorAddGroupTask, self).__init__(module, cls)
-
-        self.form = AddGroupForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Add group"
-
-class NegotiatorEditRegroup(NegotiatorGroupTask):
-    def __init__(self, module, cls):
-        super(NegotiatorEditRegroupTask, self).__init__(module, cls)
-
-        self.form = EditRegroupForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit autoregroup"
-
-class NegotiatorEditPrioFactor(NegotiatorGroupTask):
-    def __init__(self, module, cls):
-        super(NegotiatorEditPrioFactorTask, self).__init__(module, cls)
-
-        self.form = EditPrioFactorForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit priority factor"
-
-class NegotiatorEditDynamicQuota(NegotiatorGroupTask):
-    def __init__(self, module, cls):
-        super(NegotiatorEditDynamicQuotaTask, self).__init__(module, cls)
-
-        self.form = EditDynamicQuotaForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit dynamic quota"
-
-class NegotiatorEditStaticQuota(NegotiatorGroupTask):
-    def __init__(self, module, cls):
-        super(NegotiatorEditStaticQuotaTask, self).__init__(module, cls)
-
-        self.form = EditStaticQuotaForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit static quota"
-
-class NegotiatorUserTask(NegotiatorGroupTask):
-    def do_enter(self, session, ng):
-        try:
-            negotiator, group = ng
-        except:
-            raise Exception("Must supply group for user forms")
-        super(NegotiatorUserTask, self).do_enter(session, negotiator)
-        self.form.group.set(session, group)
-
-class NegotiatorUserPrioFactor(NegotiatorUserTask):
-    def __init__(self, module, cls):
-        super(NegotiatorUserPrioFactorTask, self).__init__(module, cls)
-
-        self.form = UserPrioFactorForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit priority factor"
-
-class NegotiatorUserRegroup(NegotiatorUserTask):
-    def __init__(self, module, cls):
-        super(NegotiatorUserRegroupTask, self).__init__(module, cls)
-
-        self.form = UserRegroupForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Edit autoregroup"

Modified: mgmt/newdata/cumin/python/cumin/grid/negotiator.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/negotiator.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/negotiator.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -13,11 +13,32 @@
 from cumin.util import *
 from cumin.widgets import *
 
-import main
+from daemon import *
 
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.grid.negotiator")
 
+class NegotiatorFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.mrg_grid.Negotiator
+
+        super(NegotiatorFrame, self).__init__(app, name, cls)
+
+        self.start = DaemonStart(app, self, "NEGOTIATOR")
+        self.stop = DaemonStop(app, self, "NEGOTIATOR")
+
+        self.group_add = NegotiatorGroupAdd(app, self)
+
+        self.edit_dynamic_quota = NegotiatorEditDynamicQuota(app, self)
+        self.edit_static_quota = NegotiatorEditStaticQuota(app, self)
+        self.edit_prio_factor = NegotiatorEditPrioFactor(app, self)
+        self.user_prio_factor = NegotiatorUserPrioFactor(app, self)
+        self.edit_regroup = NegotiatorEditRegroup(app, self)
+        self.user_regroup = NegotiatorUserRegroup(app, self)
+
+        overview = NegotiatorOverview(app, "overview", self.object, self)
+        self.view.add_tab(overview)
+
 class NegotiatorSelector(ObjectSelector):
     def __init__(self, app, name, pool):
         cls = app.rosemary.mrg_grid.Negotiator
@@ -26,50 +47,18 @@
 
         self.pool = pool
 
-        self.add_filter(self.pool, cls.Pool, cls.Pool)
+        self.add_filter(self.pool, cls.Pool)
 
         frame = "main.grid.pool.negotiator"
         col = ObjectLinkColumn(app, "name", cls.Name, cls._id, frame)
         self.add_column(col)
 
-        # self.add_attribute_column(cls.MyAddress)
         self.add_attribute_column(cls.Machine)
         self.add_attribute_column(cls.System)
 
-        # self.add_selection_task(main.module.negotiator_set_start)
-        # self.add_selection_task(main.module.negotiator_set_stop)
+        self.start = DaemonSelectionStart(app, self, "NEGOTIATOR")
+        self.stop = DaemonSelectionStop(app, self, "NEGOTIATOR")
 
-class NegotiatorFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.mrg_grid.Negotiator
-
-        super(NegotiatorFrame, self).__init__(app, name, cls)
-
-        # self.icon_href = "resource?name=negotiator-36.png"
-
-class OldNegotiatorFrame(CuminFrame):
-    def __init__(self, app, name):
-        super(OldNegotiatorFrame, self).__init__(app, name)
-
-        self.object = NegotiatorParameter(app, "id")
-        self.add_parameter(self.object)
-
-        self.view = NegotiatorView(app, "view", self.object)
-        self.add_mode(self.view)
-
-class NegotiatorView(CuminView):
-    def __init__(self, app, name, negotiator):
-        super(NegotiatorView, self).__init__(app, name, negotiator)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        self.overview = NegotiatorOverview(app, "overview", negotiator)
-        self.tabs.add_tab(self.overview)
-
-        self.details = CuminDetails(app, "details", negotiator)
-        self.tabs.add_tab(self.details)
-
 class QmfGroupColumn(ItemTableColumn):
     def __init__(self, app, name, getter, negotiator, task):
         super(QmfGroupColumn, self).__init__(app, name)
@@ -104,7 +93,8 @@
     def render_data(self, session, data):
         # is user
         if "." in data[0] and self.user_task:
-            href = "%s" % self.user_task.get_href(session, (self.negotiator.get(session), data[0]))
+            href = "%s" % self.user_task.get_href \
+                (session, (self.negotiator.get(session), data[0]))
         else:
             href = self.task.get_href(session, self.negotiator.get(session))
         content = data[2][2] and str(data[1]) or "NOT SET"
@@ -114,7 +104,7 @@
         return "Edit the %s" % self.title
 
 class NegotiatorOverview(ItemTable):
-    def __init__(self, app, name, negotiator):
+    def __init__(self, app, name, negotiator, frame):
         super(NegotiatorOverview, self).__init__(app, name)
 
         self.update_enabled = False
@@ -130,7 +120,7 @@
         self.buttons.html_class = "buttons"
         self.add_child(self.buttons)
 
-        task = main.module.negotiator_add_group
+        task = frame.group_add
         button = EditButton(app, "add_group_button", task, negotiator)
         self.buttons.add_child(button)
 
@@ -142,28 +132,28 @@
         self.add_column(col)
         self.set_default_column(col)
 
-        task = main.module.negotiator_edit_dynamic_quota
+        task = frame.edit_dynamic_quota
         col = self.DynamicColumn(app, "dynamic", self.group_helper.get_dyn_quota, negotiator, task)
         col.title = "Dynamic Quota"
         self.add_column(col)
 
-        task = main.module.negotiator_edit_static_quota
+        task = frame.edit_static_quota
         col = QmfGroupColumn(app, "static", self.group_helper.get_static_quota, negotiator, task)
         col.title = "Static Quota"
         self.add_column(col)
 
-        task = main.module.negotiator_edit_prio_factor
+        task = frame.edit_prio_factor
         col = QmfGroupColumn(app, "factor", self.group_helper.get_priority_factor, negotiator, task)
         col.title = "Priority Factor"
         col.user = True
-        col.user_task = main.module.negotiator_user_prio_factor
+        col.user_task = frame.user_prio_factor
         self.add_column(col)
 
-        task = main.module.negotiator_edit_regroup
+        task = frame.edit_regroup
         col = QmfGroupColumn(app, "regroup", self.group_helper.get_regroups, negotiator, task)
         col.title = "Auto Regroup"
         col.user = True
-        col.user_task = main.module.negotiator_user_regroup
+        col.user_task = frame.user_regroup
         self.add_column(col)
 
     def render_title(self, session):
@@ -400,15 +390,12 @@
                 self.items.set(session, users)
             return users
 
-class AddGroupForm(CuminTaskForm):
+class GroupAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
-        super(AddGroupForm, self).__init__(app, name, task)
+        super(GroupAddForm, self).__init__(app, name, task)
 
         self.defer_enabled = True
 
-        self.object = NegotiatorParameter(app, "negotiator")
-        self.add_parameter(self.object)
-
         self.group_helper = GroupHelper(app, "groups", self.object)
         self.add_child(self.group_helper)
 
@@ -431,7 +418,7 @@
             new_groups = ", ".join(original_groups)
             self.task.invoke(session, negotiator, "GROUP_NAMES", new_groups)
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
     def is_valid(self, group):
         ret = False
@@ -528,7 +515,7 @@
                     changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
     def is_valid_factor(self, value):
         try:
@@ -574,7 +561,7 @@
                     changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
 class EditDynamicQuotaForm(GroupForm):
     def __init__(self, app, name, task):
@@ -609,7 +596,8 @@
         writer = Writer()
 
         groups = self.group_helper.get_dyn_quota(session)
-        groups = self.group_helper.append_unclaimed_dyn_quota(session, groups, force=True)
+        groups = self.group_helper.append_unclaimed_dyn_quota \
+            (session, groups, force=True)
         for group in groups:
             if group[0] == "Unclaimed":
                 self.unclaimed_tmpl.render(writer, session, group)
@@ -639,11 +627,12 @@
                 continue
             quota = self.check_quota(new_value, original_value)
             if quota:
-                self.task.invoke(session, negotiator, "GROUP_QUOTA_DYNAMIC_"+group, quota)
+                self.task.invoke(session, negotiator,
+                                 "GROUP_QUOTA_DYNAMIC_" + group, quota)
                 changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
     def check_quota(self, quota, original):
         try:
@@ -717,7 +706,7 @@
                 changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
 class EditRegroupForm(GroupForm):
     def __init__(self, app, name, task):
@@ -795,7 +784,7 @@
                 changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
 class UserRegroupForm(EditRegroupForm):
     def __init__(self, app, name, task):
@@ -830,7 +819,7 @@
                 changed = True
         if changed:
             self.task.invoke(session, negotiator, "Reconfig", None)
-        self.task.exit_with_redirect(session, negotiator)
+        self.task.exit_with_redirect(session)
 
 class PriorityPieChart(StatFlashChart):
     def __init__(self, app, name, negotiator, groups):
@@ -871,32 +860,117 @@
         params.extend(vals)
         return params
 
-class NegotiatorStartForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(NegotiatorStartForm, self).__init__(app, name, task)
+class EditButton(ActionSet):
+    def __init__(self, app, name, task, negotiator):
+        super(EditButton, self).__init__(app, name)
 
-        self.object = NegotiatorParameter(app, "negotiator")
-        self.add_parameter(self.object)
+        link = ObjectTaskLink(app, "edit", task)
+        self.add_child(link)
 
-class NegotiatorStopForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(NegotiatorStopForm, self).__init__(app, name, task)
+class NegotiatorLimitSet(ObjectTask):
+    def __init__(self, app, frame):
+        super(NegotiatorLimitSet, self).__init__(app, frame)
 
-        self.object = NegotiatorParameter(app, "negotiator")
-        self.add_parameter(self.object)
+        self.form = NegotiatorLimitSetForm(module.app, self.name, self)
 
-class NegotiatorSetTaskForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(NegotiatorSetTaskForm, self).__init__(app, name, task)
+    def do_enter(self, session, limit):
+        self.form.negotiator.set(session, limit[0])
+        self.form.limit_name.set(session, limit[1])
 
-        item = NegotiatorParameter(app, "item")
+    def get_title(self, session):
+        return "Set limit"
 
-        self.object = ListParameter(app, "negotiator", item)
-        self.add_parameter(self.object)
+    def do_invoke(self, invoc, negotiator, name, max):
+        assert isinstance(negotiator, Negotiator)
 
-class EditButton(ActionSet):
-    def __init__(self, app, name, task, negotiator):
-        super(EditButton, self).__init__(app, name)
+        negotiator.SetLimit(completion, name, max)
 
-        link = TaskLink(app, "edit", task, negotiator)
-        self.add_child(link)
+        # XXX 
+        def completion():
+            pass
+
+        negotiator.Reconfig(completion)
+
+class NegotiatorGroupTask(ObjectTask):
+    def do_exit(self, session):
+        self.app.main_page.main.grid.pool.negotiator.view.show(session)
+
+    def do_invoke(self, completion, session, negotiator, group, value):
+        assert isinstance(negotiator, Negotiator)
+
+        if group == "Reconfig":
+            negotiator.Reconfig(completion)
+        else:
+            negotiator.SetRawConfig(completion, group, value)
+
+class NegotiatorGroupAdd(NegotiatorGroupTask):
+    def __init__(self, app, frame):
+        super(NegotiatorGroupAdd, self).__init__(app, frame)
+
+        self.form = GroupAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add group"
+
+class NegotiatorEditRegroup(NegotiatorGroupTask):
+    def __init__(self, app, frame):
+        super(NegotiatorEditRegroup, self).__init__(app, frame)
+
+        self.form = EditRegroupForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit autoregroup"
+
+class NegotiatorEditPrioFactor(NegotiatorGroupTask):
+    def __init__(self, app, frame):
+        super(NegotiatorEditPrioFactor, self).__init__(app, frame)
+
+        self.form = EditPrioFactorForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit priority factor"
+
+class NegotiatorEditDynamicQuota(NegotiatorGroupTask):
+    def __init__(self, app, frame):
+        super(NegotiatorEditDynamicQuota, self).__init__(app, frame)
+
+        self.form = EditDynamicQuotaForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit dynamic quota"
+
+class NegotiatorEditStaticQuota(NegotiatorGroupTask):
+    def __init__(self, app, frame):
+        super(NegotiatorEditStaticQuota, self).__init__(app, frame)
+
+        self.form = EditStaticQuotaForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit static quota"
+
+class NegotiatorUserTask(NegotiatorGroupTask):
+    def do_enter(self, session, ng):
+        try:
+            negotiator, group = ng
+        except:
+            raise Exception("Must supply group for user forms")
+        super(NegotiatorUserTask, self).do_enter(session, negotiator)
+        self.form.group.set(session, group)
+
+class NegotiatorUserPrioFactor(NegotiatorUserTask):
+    def __init__(self, app, frame):
+        super(NegotiatorUserPrioFactor, self).__init__(app, frame)
+
+        self.form = UserPrioFactorForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit priority factor"
+
+class NegotiatorUserRegroup(NegotiatorUserTask):
+    def __init__(self, app, frame):
+        super(NegotiatorUserRegroup, self).__init__(app, frame)
+
+        self.form = UserRegroupForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Edit autoregroup"

Modified: mgmt/newdata/cumin/python/cumin/grid/negotiator.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/negotiator.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/negotiator.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -8,14 +8,14 @@
 
 [NegotiatorOverview.html]
 <div id="{id}" class="CuminTable GroupTable">
-    <div class="sactions">
-      <h2>Actions:</h2>
-      {buttons}
-    </div>
-<table {class}>
-  <thead><tr>{headers}</tr></thead>
-  <tbody>{items}</tbody>
-</table>
+  <div class="sactions">
+    <h2>Actions:</h2>
+    {buttons}
+  </div>
+  <table {class}>
+    <thead><tr>{headers}</tr></thead>
+    <tbody>{items}</tbody>
+  </table>
 </div>
 
 [GroupForm.css]

Modified: mgmt/newdata/cumin/python/cumin/grid/pool.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/pool.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/pool.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -57,6 +57,9 @@
         self.submission = SubmissionFrame(app, "submission")
         self.add_mode(self.submission)
 
+        #self.job = JobFrame(app, "job")
+        #self.add_mode(self.job)
+
         self.slot = SlotFrame(app, "slot")
         self.add_mode(self.slot)
 
@@ -66,9 +69,20 @@
         self.negotiator = NegotiatorFrame(app, "negotiator")
         self.add_mode(self.negotiator)
 
-        submissions = SubmissionSelector(app, "submissions", self.object)
+        #self.collector = CollectorFrame(app, "coll")
+        #elf.add_mode(self.collector)
+
+        #self.limit = LimitFrame(app, "limit", negotiator)
+        #self.add_mode(self.limit)
+
+        overview = PoolOverview(app, "overview", self.object)
+        self.view.add_tab(overview)
+
+        submissions = SubmissionSelector(app, "submissions")
         self.view.add_tab(submissions)
 
+        # XXX submissions.add_filter(self.object, submissions.cls.Pool)
+
         slots = SlotSelector(app, "slots", self.object)
         self.view.add_tab(slots)
 
@@ -78,107 +92,16 @@
         negotiators = NegotiatorSelector(app, "negotiators", self.object)
         self.view.add_tab(negotiators)
 
-class OldPoolFrame(CuminFrame):
-    def __init__(self, app, name):
-        super(OldPoolFrame, self).__init__(app, name)
+        #self.limits = LimitSet(app, "limits", negotiator)
+        #self.view.add_tab(self.limits)
 
-        self.object = PoolParameter(app, "id")
-        self.add_parameter(self.object)
+        self.submission_add = SubmissionAdd(app, self)
 
-        negotiator = PoolNegotiatorAttribute(app, "negotiator", self.object)
-        self.add_attribute(negotiator)
-
-        self.view = PoolView(app, "view", self.object)
-        self.add_mode(self.view)
-
-        self.submission = SubmissionFrame(app, "submission")
-        self.add_mode(self.submission)
-
-        self.job = JobFrame(app, "job")
-        self.add_mode(self.job)
-
-        self.slot = SlotFrame(app, "slot")
-        self.add_mode(self.slot)
-
-        self.scheduler = SchedulerFrame(app, "sched", self.object)
-        self.add_mode(self.scheduler)
-
-        self.collector = CollectorFrame(app, "coll")
-        self.add_mode(self.collector)
-
-        self.limit = LimitFrame(app, "limit", negotiator)
-        self.add_mode(self.limit)
-
-        self.negotiator = NegotiatorFrame(app, "neg")
-        self.add_mode(self.negotiator)
-
-class PoolView(CuminView):
-    def __init__(self, app, name, pool):
-        super(PoolView, self).__init__(app, name, pool)
-
-        self.pool = pool
-
-        negotiator = PoolNegotiatorAttribute(app, "negotiator", self.pool)
-        self.add_attribute(negotiator)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        self.overview = PoolOverview(app, "overview", self.pool)
-        self.tabs.add_tab(self.overview)
-
-        self.submissions = PoolSubmissionSet(app, "submissions", self.pool)
-        self.tabs.add_tab(self.submissions)
-
-        self.slots = PoolSlotSet(app, "slots", self.pool)
-        self.tabs.add_tab(self.slots)
-
-        self.schedulers = PoolSchedulerSet(app, "schedulers", self.pool)
-        self.tabs.add_tab(self.schedulers)
-
-        self.negotiators = PoolNegotiatorSet(app, "negotiators", self.pool)
-        self.tabs.add_tab(self.negotiators)
-
-        self.collectors = PoolCollectorSet(app, "collectors", self.pool)
-        self.tabs.add_tab(self.collectors)
-
-        self.limits = LimitSet(app, "limits", negotiator)
-        self.tabs.add_tab(self.limits)
-
     def do_process(self, session):
-        self.limits.limit_count.process(session)
+        #self.limits.limit_count.process(session)
+
         super(PoolView, self).do_process(session)
 
-class PoolSubmissionSet(SubmissionSet):
-    def __init__(self, app, name, pool):
-        super(PoolSubmissionSet, self).__init__(app, name)
-
-        self.pool = pool
-
-        task = main.module.submission_add
-        link = TaskLink(app, "add", task, self.pool)
-        self.links.add_child(link)
-
-    def get_submission_href(self, session, id):
-        submission = Identifiable(id)
-        return main.module.frame.pool.submission.get_href(session, submission)
-
-    def get_submitter_href(self, session, id):
-        submitter = Identifiable(id)
-        return main.module.frame.pool.scheduler.submitter.get_href \
-            (session, submitter)
-
-    def get_scheduler_href(self, session, id):
-        scheduler = Identifiable(id)
-        return main.module.frame.pool.scheduler.get_href(session, scheduler)
-
-    def render_sql_where(self, session):
-        return "where d.pool = %(pool)s"
-
-    def get_sql_values(self, session):
-        pool = self.pool.get(session)
-        return {"pool": pool.id}
-
 class PoolOverview(Widget):
     def __init__(self, app, name, pool):
         super(PoolOverview, self).__init__(app, name)
@@ -234,8 +157,8 @@
         super(GridGeneralStatSet, self).__init__(app, name, object)
 
         self.attrs = ("NumJobs", "SubmitsInProgress",
-                "SubmitsQueued", "SubmitsAllowed",
-                "SubmitsWanted", "RunningJobs", "IdleJobs")
+                      "SubmitsQueued", "SubmitsAllowed",
+                      "SubmitsWanted", "RunningJobs", "IdleJobs")
 
     def do_render(self, session):
         grid = self.object.get(session)
@@ -401,7 +324,8 @@
 
         def get_click(self, session, state):
             href = self.parent.render_slots_href(session)
-            return "return slot_vis('%s', this, '%s', '%s')" % (state, self.parent.path, href)
+            return "return slot_vis('%s', this, '%s', '%s')" % \
+                (state, self.parent.path, href)
 
 class PoolSlotFullPage(FlashFullPage):
     def __init__(self, app, name):

Modified: mgmt/newdata/cumin/python/cumin/grid/scheduler.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/scheduler.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/scheduler.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,5 +1,3 @@
-import logging
-
 from random import choice
 
 from wooly import *
@@ -7,6 +5,7 @@
 from wooly.forms import *
 from wooly.resources import *
 from wooly.tables import *
+
 from cumin.objectframe import *
 from cumin.objectselector import *
 from cumin.formats import *
@@ -16,13 +15,38 @@
 from cumin.util import *
 from cumin.widgets import *
 
+from daemon import *
 from job import *
 from submitter import *
 from submission import *
 
 strings = StringCatalog(__file__)
-log = logging.getLogger("cumin.scheduler")
+log = logging.getLogger("cumin.grid.scheduler")
 
+class SchedulerFrame(ObjectFrame):
+    def __init__(self, app, name, pool):
+        cls = app.rosemary.mrg_grid.Scheduler
+
+        super(SchedulerFrame, self).__init__(app, name, cls)
+
+        self.submitter = SubmitterFrame(app, "submitter")
+        self.add_mode(self.submitter)
+
+        overview = SchedulerOverview(app, "overview", self.object)
+        self.view.add_tab(overview)
+
+        submissions = SubmissionSelector(app, "submissions")
+        self.view.add_tab(submissions)
+
+        cls = submissions.cls
+        submissions.add_reference_filter(self.object, cls.schedulerRef)
+
+        submitters = SubmitterSelector(app, "submitters", self.object)
+        self.view.add_tab(submitters)
+
+        self.start = DaemonStart(app, self, "SCHEDD")
+        self.stop = DaemonStop(app, self, "SCHEDD")
+
 class SchedulerSelector(ObjectSelector):
     def __init__(self, app, name, pool):
         cls = app.rosemary.mrg_grid.Scheduler
@@ -31,7 +55,7 @@
 
         self.pool = pool
 
-        self.add_filter(self.pool, cls.Pool, cls.Pool)
+        self.add_filter(self.pool, cls.Pool)
 
         frame = "main.grid.pool.scheduler"
         col = ObjectLinkColumn(app, "name", cls.Name, cls._id, frame)
@@ -42,26 +66,9 @@
         self.add_attribute_column(cls.TotalRunningJobs)
         self.add_attribute_column(cls.TotalHeldJobs)
 
-        #self.add_selection_task(main.module.scheduler_set_start)
-        #self.add_selection_task(main.module.scheduler_set_stop)
+        self.start = DaemonSelectionStart(app, self, "SCHEDD")
+        self.stop = DaemonSelectionStop(app, self, "SCHEDD")
 
-class SchedulerFrame(ObjectFrame):
-    def __init__(self, app, name, pool):
-        cls = app.rosemary.mrg_grid.Scheduler
-
-        super(SchedulerFrame, self).__init__(app, name, cls)
-
-        self.submitter = SubmitterFrame(app, "submitter")
-        self.add_mode(self.submitter)
-
-        submissions = SubmissionSelector(app, "submissions", pool)
-        submissions.add_reference_filter \
-            (self.object, submissions.cls.schedulerRef)
-        self.view.add_tab(submissions)
-
-        submitters = SubmitterSelector(app, "submitters", self.object)
-        self.view.add_tab(submitters)
-
 class SchedulerSelectField(ScalarField):
     def __init__(self, app, name, pool):
         super(SchedulerSelectField, self).__init__(app, name, None)
@@ -109,49 +116,17 @@
             if item is self.param.get(session):
                 return "selected=\"selected\""
 
-class OldSchedulerFrame(CuminFrame):
-    def __init__(self, app, name, pool):
-        super(OldSchedulerFrame, self).__init__(app, name)
-
-        self.object = SchedulerParameter(app, "id")
-        self.add_parameter(self.object)
-
-        self.view = SchedulerView(app, "view", self.object)
-        self.add_mode(self.view)
-
-        self.submitter = SubmitterFrame(app, "sub", self.object)
-        self.add_mode(self.submitter)
-
-class SchedulerView(CuminView):
-    def __init__(self, app, name, scheduler):
-        super(SchedulerView, self).__init__(app, name, scheduler)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        stats = SchedulerStats(app, "stats", scheduler)
-        self.tabs.add_tab(stats)
-
-        submissions = SchedulerSubmissionSet(app, "submissions", scheduler)
-        self.tabs.add_tab(submissions)
-
-        submitters = SchedulerSubmitterSet(app, "submitters", scheduler)
-        self.tabs.add_tab(submitters)
-
-        details = CuminDetails(app, "details", scheduler)
-        self.tabs.add_tab(details)
-
 class SchedulerGeneralStatSet(StatSet):
     def __init__(self, app, name, object):
         super(SchedulerGeneralStatSet, self).__init__(app, name, object)
 
         self.attrs = ("NumUsers", "TotalRunningJobs",
-                       "TotalIdleJobs", "TotalHeldJobs",
-                       "TotalJobAds", "TotalRemovedJobs")
+                      "TotalIdleJobs", "TotalHeldJobs",
+                      "TotalJobAds", "TotalRemovedJobs")
 
-class SchedulerStats(Widget):
+class SchedulerOverview(Widget):
     def __init__(self, app, name, scheduler):
-        super(SchedulerStats, self).__init__(app, name)
+        super(SchedulerOverview, self).__init__(app, name)
 
         stats = SchedulerGeneralStatSet(app, "general", scheduler)
         self.add_child(stats)
@@ -167,7 +142,7 @@
         self.add_child(chart)
 
     def render_title(self, session):
-        return "Statistics"
+        return "Overview"
 
     class UsersChart(StatFlashChart):
         def render_title(self, session):
@@ -176,44 +151,3 @@
     class JobsChart(StatFlashChart):
         def render_title(self, session):
             return "Jobs"
-
-class SchedulerJobSet(JobTab):
-    def __init__(self, app, name, pool):
-        super(SchedulerJobSet, self).__init__(app, name, pool)
-
-    def get_visible_columns(self, session):
-        return self.get_request_visible_columns(session, ["custom_group", "submitter"])
-
-    def render_sql_where(self, session):
-        scheduler = self.frame.object.get(session)
-        phase_sql = self.get_phase_sql(session)
-        scheduler_sql = "j.scheduler_id = %i" % scheduler.id
-        return "where %s" % " and ".join([phase_sql, scheduler_sql])
-
-    def render_title(self, session):
-        scheduler = self.frame.object.get(session)
-        where_scheduler = "scheduler_id = %i" % scheduler.id
-        return "Jobs %s" % fmt_count(Job.select(where_scheduler).count())
-
-class SchedulerStartForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(SchedulerStartForm, self).__init__(app, name, task)
-
-        self.object = SchedulerParameter(app, "scheduler")
-        self.add_parameter(self.object)
-
-class SchedulerStopForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(SchedulerStopForm, self).__init__(app, name, task)
-
-        self.object = SchedulerParameter(app, "scheduler")
-        self.add_parameter(self.object)
-
-class SchedulerSetTaskForm(CuminTaskForm):
-    def __init__(self, app, name, task):
-        super(SchedulerSetTaskForm, self).__init__(app, name, task)
-
-        item = SchedulerParameter(app, "item")
-
-        self.object = ListParameter(app, "scheduler", item)
-        self.add_parameter(self.object)

Modified: mgmt/newdata/cumin/python/cumin/grid/scheduler.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/scheduler.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/scheduler.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,4 +1,4 @@
-[SchedulerStats.html]
+[SchedulerOverview.html]
 <table class="twocol">
   <tbody>
   <tr>

Modified: mgmt/newdata/cumin/python/cumin/grid/submission.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/submission.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/submission.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -3,25 +3,26 @@
 
 from cumin.objectframe import *
 from cumin.objectselector import *
+from cumin.objecttask import *
 from cumin.widgets import *
 from cumin.util import *
 from job import JobSet
 
-import main
-
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.grid.submission")
 
+class SubmissionFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.mrg_grid.Submission
+
+        super(SubmissionFrame, self).__init__(app, name, cls)
+
 class SubmissionSelector(ObjectSelector):
-    def __init__(self, app, name, pool):
+    def __init__(self, app, name):
         cls = app.rosemary.mrg_grid.Submission
 
         super(SubmissionSelector, self).__init__(app, name, cls)
 
-        self.pool = pool
-
-        # XXX self.add_filter(self.pool, cls.Pool, cls.Pool)
-
         frame = "main.grid.pool.submission"
         col = ObjectLinkColumn(app, "name", cls.Name, cls._id, frame)
         self.add_column(col)
@@ -30,175 +31,125 @@
         self.add_attribute_column(cls.Running)
         self.add_attribute_column(cls.Completed)
 
-class SubmissionFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.mrg_grid.Submission
-
-        super(SubmissionFrame, self).__init__(app, name, cls)
-
-class SubmissionSet(CuminTable):
-    def __init__(self, app, name):
-        super(SubmissionSet, self).__init__(app, name)
-
-        col = self.NameColumn(app, "name")
-        col.width = "40%"
-        self.add_column(col)
-
-        self.scheduler_col = self.SchedulerColumn(app, "scheduler")
-        self.add_column(self.scheduler_col)
-
-        self.submitter_col = self.SubmitterColumn(app, "submitter")
-        self.width = "15%"
-        self.add_column(self.submitter_col)
-
-        col = self.IdleColumn(app, "idle")
-        self.add_column(col)
-
-        col = self.RunningColumn(app, "running")
-        self.add_column(col)
-
-        col = self.CompletedColumn(app, "completed")
-        self.add_column(col)
-
-    def get_submission_href(self, session, id):
-        raise Exception("Not implemented")
-
-    def get_submitter_href(self, session, id):
-        raise Exception("Not implemented")
-
-    def get_scheduler_href(self, session, id):
-        raise Exception("Not implemented")
-
+class SubmissionJobSet(JobSet):
     def render_title(self, session):
-        return "Submissions %s" % fmt_count(self.get_item_count(session))
+        return "Jobs"
 
-    class NameColumn(TopTableColumn):
-        def render_title(self, session):
-            return "Name"
+class SubmissionAdd(ObjectTask):
+    EXPR_TYPE, INTEGER_TYPE, FLOAT_TYPE, STRING_TYPE = 0, 1, 2, 3
+    UNIVERSE = {"VANILLA": 5,
+                "SCHEDULER": 7,
+                "GRID": 9,
+                "JAVA": 10,
+                "PARALLEL": 11,
+                "LOCAL": 12,
+                "VM": 13}
 
-        def render_content(self, session, data):
-            href = self.parent.get_submission_href(session, data["id"])
-            return fmt_link(href, data["name"])
+    def __init__(self, app, frame):
+        super(SubmissionAdd, self).__init__(app, frame)
 
-    class SchedulerColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Scheduler"
+        self.form = SubmissionAddForm(app, self.name, self)
 
-        def render_content(self, session, data):
-            href = self.parent.get_scheduler_href \
-                (session, data["scheduler_id"])
-            return fmt_link(href, data["scheduler_name"])
+    def get_title(self, session):
+        return "Create submission"
 
-    class SubmitterColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Submitter"
+    def do_invoke(self, invoc, scheduler,
+                  description,
+                  executable,
+                  args=None,
+                  iwd="/tmp",
+                  stdin=None,
+                  stdout=None,
+                  stderr=None,
+                  requirements="TRUE",
+                  universe="VANILLA"):
+        user_name = invoc.user.name
 
-        def render_content(self, session, data):
-            href = self.parent.get_submitter_href \
-                (session, data["scheduler_id"])
-            return fmt_link(href, data["owner"])
+        ad = {
+            "Submission":   {"TYPE": self.STRING_TYPE,
+                             "VALUE": condor_string(description)},
+            "Cmd":          {"TYPE": self.STRING_TYPE,
+                             "VALUE": condor_string(executable)},
+            "Args":         {"TYPE": self.STRING_TYPE,
+                             "VALUE": condor_string(args)},
+            "Requirements": {"TYPE": self.EXPR_TYPE,
+                             "VALUE": requirements},
+            "JobUniverse":  {"TYPE": self.INTEGER_TYPE,
+                             "VALUE": str(self.UNIVERSE[universe])},
+            "Iwd":          {"TYPE": self.STRING_TYPE,
+                             "VALUE": condor_string(iwd)},
+            "Owner":        {"TYPE": self.STRING_TYPE,
+                             "VALUE": "guest3"}
+            }
 
-    class IdleColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Idle Jobs"
+#            "User":         {"TYPE": self.STRING_TYPE,
+#                             "VALUE": condor_string("example at example.com")}
 
-    class RunningColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Running Jobs"
+        scheduler.Submit(completion, ad, None)
 
-    class CompletedColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Completed Jobs"
+def condor_string(string):
+    return string
 
-class OldSubmissionFrame(CuminFrame):
-    def __init__(self, app, name):
-        super(OldSubmissionFrame, self).__init__(app, name)
-
-        self.object = SubmissionParameter(app, "submission")
-        self.add_parameter(self.object)
-
-        self.view = SubmissionView(app, "view", self.object)
-        self.add_child(self.view)
-
-class SubmissionView(CuminView):
-    def __init__(self, app, name, submission):
-        super(SubmissionView, self).__init__(app, name, submission)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        self.jobs = SubmissionJobSet(app, "jobs", submission)
-        self.tabs.add_tab(self.jobs)
-
-class SubmissionJobSet(JobSet):
-    def render_title(self, session):
-        return "Jobs"
-
-class SubmissionAddForm(FoldingFieldSubmitForm):
+class SubmissionAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
-        super(SubmissionAddForm, self).__init__(app, name)
+        super(SubmissionAddForm, self).__init__(app, name, task)
 
+        # XXX
         self.pool = PoolParameter(app, "pool")
         self.add_parameter(self.pool)
 
-        self.task = task
-
         from scheduler import SchedulerSelectField # XXX
 
         self.scheduler = SchedulerSelectField(app, "scheduler", self.pool)
         self.scheduler.required = True
         self.scheduler.help = "Create submission at this scheduler"
-        self.main_fields.add_field(self.scheduler)
+        self.add_field(self.scheduler)
 
         self.description = self.DescriptionField(app, "description")
         self.description.input.size = 50
         self.description.required = True
         self.description.help = "This text will identify the submission"
-        self.main_fields.add_field(self.description)
+        self.add_field(self.description)
 
         self.command = self.CommandField(app, "command")
         self.command.input.columns = 50
         self.command.required = True
         self.command.help = "The path to the executable and any arguments"
-        self.main_fields.add_field(self.command)
+        self.add_field(self.command)
 
         self.requirements = self.RequirementsField(app, "requirements")
         self.requirements.input.columns = 50
         self.requirements.help = "Attributes controlling where and when " + \
             "this submission will run"
-        self.main_fields.add_field(self.requirements)
+        self.add_field(self.requirements)
 
         self.directory = self.WorkingDirectoryField(app, "directory")
         self.directory.input.size = 50
         self.directory.help = "Run the process in this directory"
-        self.extra_fields.add_field(self.directory)
+        self.add_extra_field(self.directory)
 
         self.stdin = self.StdinField(app, "stdin")
         self.stdin.input.size = 50
         self.stdin.help = "Get process input from this file"
-        self.extra_fields.add_field(self.stdin)
+        self.add_extra_field(self.stdin)
 
         self.stdout = self.StdoutField(app, "stdout")
         self.stdout.input.size = 50
         self.stdout.help = "Send process output to this file"
-        self.extra_fields.add_field(self.stdout)
+        self.add_extra_field(self.stdout)
 
         self.stderr = self.StderrField(app, "stderr")
         self.stderr.input.size = 50
         self.stderr.help = "Send error output to this file"
-        self.extra_fields.add_field(self.stderr)
+        self.add_extra_field(self.stderr)
 
         #self.options = self.OptionsField(app, "options")
-        #self.main.add_field(self.options)
+        #self.add_extra_field(self.options)
 
         self.attributes_ = self.AttributesField(app, "attributes")
         self.attributes_.input.columns = 50
-        self.extra_fields.add_field(self.attributes_)
+        self.add_extra_field(self.attributes_)
 
-    def validate(self, session):
-        self.main_fields.validate(session)
-        self.extra_fields.validate(session)
-
     def process_submit(self, session):
         self.validate(session)
 
@@ -228,14 +179,11 @@
                              stdout=stdout,
                              stderr=stderr,
                              requirements=requirements)
-#                             universe=universe) # XXX
 
-            self.task.exit_with_redirect(session, scheduler)
+            #                universe=universe) # XXX
+            
+            self.task.exit_with_redirect(session)
 
-    def render_title(self, session):
-        pool = self.pool.get(session)
-        return self.task.get_description(session, pool)
-
     class TemplateField(FormField):
         def __init__(self, app, name):
             super(SubmissionAddForm.TemplateField, self).__init__(app, name)
@@ -345,4 +293,3 @@
         def render_content(self, session, data):
             since = data["qmf_create_time"]
             return fmt_duration(time() - secs(since))
-

Modified: mgmt/newdata/cumin/python/cumin/grid/submission.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/submission.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/submission.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,27 +1,3 @@
-[SubmissionSet.sql]
-select
-  s.id,
-  s.name,
-  s.owner,
-  c.idle,
-  c.running,
-  c.completed,
-  d.id as scheduler_id,
-  d.name as scheduler_name
-from submission as s
-inner join scheduler as d on s.scheduler_id = d.id
-inner join submission_stats as c on s.stats_curr_id = c.id
-{sql_where}
-{sql_order_by}
-{sql_limit}
-
-[SubmissionSet.count_sql]
-select count(*)
-from submission as s
-inner join scheduler as d on s.scheduler_id = d.id
-inner join submission_stats as c on s.stats_curr_id = c.id
-{sql_where}
-
 [TopSubmissionSet.sql]
 select
   s.id,

Modified: mgmt/newdata/cumin/python/cumin/grid/submitter.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/submitter.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/submitter.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -5,6 +5,9 @@
 from wooly.forms import *
 from wooly.resources import *
 from wooly.tables import *
+
+from cumin.objectframe import *
+from cumin.objectselector import *
 from cumin.stat import *
 from cumin.widgets import *
 from cumin.parameters import *
@@ -16,6 +19,17 @@
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.grid.submitter")
 
+class SubmitterFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.mrg_grid.Submitter
+
+        super(SubmitterFrame, self).__init__(app, name, cls)
+
+        overview = SubmitterOverview(app, "overview", self.object)
+        self.view.add_tab(overview)
+
+        # submissions XXX
+
 class SubmitterSelector(ObjectSelector):
     def __init__(self, app, name, scheduler):
         cls = app.rosemary.mrg_grid.Submitter
@@ -36,47 +50,15 @@
         self.add_attribute_column(cls.RunningJobs)
         self.add_attribute_column(cls.HeldJobs)
 
-class SubmitterFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.mrg_grid.Submitter
-
-        super(SubmitterFrame, self).__init__(app, name, cls)
-
-class OldSubmitterFrame(CuminFrame):
-    def __init__(self, app, name, pool):
-        super(OldSubmitterFrame, self).__init__(app, name)
-
-        self.object = SubmitterParameter(app, "id")
-        self.add_parameter(self.object)
-
-        self.view = SubmitterView(app, "view", self.object)
-        self.add_mode(self.view)
-
-class SubmitterView(CuminView):
-    def __init__(self, app, name, submitter):
-        super(SubmitterView, self).__init__(app, name, submitter)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        stats = SubmitterStats(app, "stats", submitter)
-        self.tabs.add_tab(stats)
-
-        submissions = SubmitterSubmissionSet(app, "submissions", submitter)
-        self.tabs.add_tab(submissions)
-
-        details = CuminDetails(app, "details", submitter)
-        self.tabs.add_tab(details)
-
 class SubmitterGeneralStatSet(StatSet):
     def __init__(self, app, name, object):
         super(SubmitterGeneralStatSet, self).__init__(app, name, object)
 
         self.attrs = ("RunningJobs", "IdleJobs", "HeldJobs")
 
-class SubmitterStats(Widget):
+class SubmitterOverview(Widget):
     def __init__(self, app, name, submitter):
-        super(SubmitterStats, self).__init__(app, name)
+        super(SubmitterOverview, self).__init__(app, name)
 
         stats = SubmitterGeneralStatSet(app, "general", submitter)
         self.add_child(stats)
@@ -86,24 +68,8 @@
         self.add_child(chart)
 
     def render_title(self, session):
-        return "Statistics"
+        return "Overview"
 
     class JobsChart(StatFlashChart):
         def render_title(self, session):
             return "Jobs"
-
-class SubmitterSubmissionSet(SubmissionSet):
-    def __init__(self, app, name, submitter):
-        super(SubmitterSubmissionSet, self).__init__(app, name)
-
-        self.submitter = submitter
-
-        self.scheduler_col.visible = False
-        self.submitter_col.visible = False
-
-    def render_sql_where(self, session):
-        return "where m.id = %(id)r"
-
-    def get_sql_values(self, session):
-        submitter = self.submitter.get(session)
-        return {"id": submitter.id}

Modified: mgmt/newdata/cumin/python/cumin/grid/submitter.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/grid/submitter.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/grid/submitter.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,4 +1,4 @@
-[SubmitterStats.html]
+[SubmitterOverview.html]
 <table class="twocol">
   <tbody>
   <tr>

Modified: mgmt/newdata/cumin/python/cumin/main.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/main.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/main.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -17,7 +17,6 @@
 from objectselector import *
 from objecttask import *
 from sqladapter import *
-from table import *
 from user import *
 from widgets import *
 
@@ -81,13 +80,13 @@
         import messaging
         import grid
         import inventory
-        import usergrid
+        #import usergrid
 
         account.Module(self, "account")
         messaging.Module(self, "messaging")
         grid.Module(self, "grid")
         inventory.Module(self, "inventory")
-        usergrid.Module(self, "usergrid")
+        #usergrid.Module(self, "usergrid")
 
         for module in self.modules:
             module.init()
@@ -345,4 +344,4 @@
 
 class TopTableFooter(Widget):
     def render(self, session):
-        return ""
\ No newline at end of file
+        return ""

Modified: mgmt/newdata/cumin/python/cumin/messaging/binding.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/binding.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/binding.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -15,6 +15,61 @@
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.messaging.exchange")
 
+class BindingSelectionRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_invoke(self, invoc, binding):
+        assert isinstance(binding, Binding)
+
+        session = self.app.model.get_session_by_object(binding)
+        session.exchange_unbind(queue=binding.queue.name,
+                                exchange=binding.exchange.name,
+                                binding_key=binding.bindingKey)
+        session.sync()
+
+        invoc.end()
+
+class BindingFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Binding
+
+        super(BindingFrame, self).__init__(app, name, cls)
+
+        self.remove = BindingRemove(app, self)
+    
+class BindingAdd(ObjectTask):
+    def __init__(self, app, frame):
+        super(BindingAdd, self).__init__(app, frame)
+
+        self.form = BindingAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add binding"
+
+    def do_invoke(self, invoc, vhost, queue, exchange, binding_key, args):
+        session = self.app.model.get_session_by_object(vhost)
+        session.exchange_bind(queue=queue.name, exchange=exchange.name,
+                              binding_key=binding_key, arguments=args)
+        session.sync()
+
+        invoc.end()
+
+class BindingRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_invoke(self, invoc, binding):
+        assert isinstance(binding, Binding)
+
+        session = self.app.model.get_session_by_object(binding)
+        session.exchange_unbind(queue=binding.queue.name,
+                                exchange=binding.exchange.name,
+                                binding_key=binding.bindingKey)
+        session.sync()
+
+        invoc.end()
+
 class BindingData(ObjectSqlAdapter):
     def __init__(self, app):
         binding = app.rosemary.org_apache_qpid_broker.Binding
@@ -36,20 +91,26 @@
 
         super(BindingSelector, self).__init__(app, name, binding, data)
 
+        frame = "main.messaging.broker.binding"
+        col = ObjectLinkColumn \
+            (app, "binding", binding.bindingKey, binding._id, frame)
+        self.add_column(col)
+
         frame = "main.messaging.broker.exchange"
         self.exchange_column = self.Exchange \
             (app, "exchange", exchange.name, exchange._id, frame)
+        self.add_column(self.exchange_column)
 
         frame = "main.messaging.broker.queue"
         self.queue_column = self.Queue \
             (app, "queue", queue.name, queue._id, frame)
+        self.add_column(self.queue_column)
 
-        self.add_attribute_column(binding.bindingKey)
         self.add_attribute_column(binding.arguments)
         self.add_attribute_column(binding.origin)
         self.add_attribute_column(binding.msgMatched)
 
-        #self.add_selection_task(main.module.binding_set_remove)
+        self.remove = BindingSelectionRemove(app, self)
 
     class Exchange(ObjectLinkColumn):
         def render_header_content(self, session):
@@ -341,16 +402,9 @@
 
     def render_exchanges(self, session):
         vhost = self.vhost.get(session)
-
         cls = self.app.rosemary.org_apache_qpid_broker.Exchange
-        
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
 
-        try:
-            exchanges = cls.get_selection(cursor, _vhostRef_id=vhost._id)
-        finally:
-            cursor.close()
+        exchanges = cls.get_selection(session.cursor, _vhostRef_id=vhost._id)
 
         # render each exchange we support
         writer = Writer()

Modified: mgmt/newdata/cumin/python/cumin/messaging/broker.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/broker.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/broker.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -6,9 +6,9 @@
 
 from cumin.formats import *
 from cumin.objectframe import *
+from cumin.objecttask import *
 from cumin.parameters import *
 from cumin.sqladapter import *
-from cumin.table import *
 from cumin.util import *
 from cumin.widgets import *
 
@@ -100,8 +100,7 @@
 
         self.icon_href = "resource?name=broker-36.png"
 
-        self.vhost = BrokerVhostAttribute(app, "vhost", self.object)
-        self.add_attribute(self.vhost)
+        self.broker = SessionAttribute(self, "broker")
 
         self.queue = QueueFrame(app, "queue") # XXX pass self.vhost
         self.add_mode(self.queue)
@@ -109,21 +108,93 @@
         self.exchange = ExchangeFrame(app, "exchange")
         self.add_mode(self.exchange)
 
+        self.binding = BindingFrame(app, "binding")
+        self.add_mode(self.binding)
+
         self.connection = ConnectionFrame(app, "connection")
         self.add_mode(self.connection)
 
         self.brokerlink = BrokerLinkFrame(app, "link")
         self.add_mode(self.brokerlink)
 
-        self.view.add_tab(QueueSelector(app, "queues", self.vhost))
-        self.view.add_tab(ExchangeSelector(app, "exchanges", self.vhost))
-        self.view.add_tab(ConnectionSelector(app, "connections", self.vhost))
-        self.view.add_tab(BrokerLinkSelector(app, "brokerlinks", self.vhost))
+        self.view = ObjectView(app, "view", self.broker)
+        self.replace_child(self.view)
 
-        self.add_summary_attribute(cls.port)
-        self.add_summary_task(app.messaging.ExchangeAdd)
-        self.add_summary_task(app.messaging.QueueAdd)
+        self.view.add_tab(QueueSelector(app, "queues", self.object))
+        self.view.add_tab(ExchangeSelector(app, "exchanges", self.object))
+        self.view.add_tab(ConnectionSelector(app, "connections", self.object))
+        self.view.add_tab(BrokerLinkSelector(app, "brokerlinks", self.object))
 
+        self.queue_add = QueueAdd(app, self)
+        self.exchange_add = ExchangeAdd(app, self)
+        self.brokerlink_add = BrokerLinkAdd(app, self)
+        self.move_messages = MoveMessages(app, self)
+
+    def get_object(self, session, id):
+        # self.object is Vhost, and we stick Broker in self.broker
+
+        broker = super(BrokerFrame, self).get_object(session, id)
+
+        self.broker.set(session, broker)
+
+        cls = self.app.rosemary.org_apache_qpid_broker.Vhost
+        args = {"_brokerRef_id": id, "name": "/"}
+
+        for obj in cls.get_selection(session.cursor, **args):
+            break
+
+        return obj
+
+    def get_title(self, session):
+        obj = self.broker.get(session)
+        
+        return "%s '%s'" % (obj._class._title, obj.get_title())
+
+class MoveMessages(ObjectTask):
+    def __init__(self, app, frame):
+        super(MoveMessages, self).__init__(app, frame)
+
+        self.form = MoveMessagesForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Move messages"
+
+    def do_invoke(self, invoc, vhost, src, dst, count):
+        self.qmf_call(invoc, vhost, src, dst, count)
+
+class MoveMessagesForm(ObjectTaskForm):
+    def __init__(self, app, name, task):
+        super(MoveMessagesForm, self).__init__(app, name, task)
+
+        self.queue = QueueParameter(app, "queue")
+        self.add_parameter(self.queue)
+
+        self.dest_queue = QueueSelectField(app, "dest", self)
+        self.add_field(self.dest_queue)
+
+        self.count = MultiplicityField(app, "count")
+        self.add_field(self.count)
+
+    def process_submit(self, session):
+        self.validate(session)
+
+        if not self.errors.get(session):
+            queue = self.queue.get(session)
+            dest_queue = self.dest_queue.get(session)
+            scount = self.count.get(session)
+
+            if scount == "all":
+                count = 0
+            elif scount == "top":
+                count = 1
+            elif scount == "N":
+                count = self.count.top_n.get_n_value(session)
+            else:
+                raise Exception("Wrong Value")
+
+            self.task.invoke(session, queue, dest_queue, count)
+            self.task.exit_with_redirect(session)
+
 class ModuleNotEnabled(Widget):
     def do_render(self, session):
         return "This module is not enabled"
@@ -304,7 +375,7 @@
         groups = self.__groups.get(session)
         if len(brokers):
             self.task.invoke(session, brokers, groups)
-        self.task.exit_with_redirect(session, brokers)
+        self.task.exit_with_redirect(session)
 
 class TopBrokerSet(CuminTable):
     def __init__(self, app, name):

Modified: mgmt/newdata/cumin/python/cumin/messaging/brokergroup.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/brokergroup.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/brokergroup.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -2,11 +2,11 @@
 from wooly import *
 from wooly.widgets import *
 from wooly.forms import *
+
 from cumin.model import *
 from cumin.widgets import *
 from cumin.parameters import *
 from cumin.sqladapter import *
-from cumin.table import *
 from cumin.formats import *
 from cumin.util import *
 
@@ -28,9 +28,25 @@
 
         self.add_attribute_column(cls.description)
 
-        self.add_task(app.messaging.BrokerGroupAdd, None)
-        self.add_selection_task(app.messaging.BrokerGroupRemove)
+        self.remove = BrokerGroupSelectionRemove(app, self)
 
+class BrokerGroupSelectionRemove(SelectionTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_invoke(self, invoc, group):
+        conn = self.app.model.get_sql_connection()
+        cursor = conn.cursor()
+
+        try:
+            group.delete(cursor)
+        finally:
+            cursor.close()
+
+        conn.commit()
+
+        invoc.end()
+
 class BrokerGroupInputSet(CheckboxInputSet):
     def __init__(self, app, name):
         super(BrokerGroupInputSet, self).__init__(app, name, None)
@@ -63,50 +79,162 @@
         brokers.group = self.object
         self.view.add_tab(brokers)
 
-class BrokerGroupForm(FieldSubmitForm):
+        self.edit = BrokerGroupEdit(app, self)
+        self.remove = BrokerGroupRemove(app, self)
+
+class BrokerGroupForm(ObjectTaskForm):
     def __init__(self, app, name, task):
-        super(BrokerGroupForm, self).__init__(app, name)
+        super(BrokerGroupForm, self).__init__(app, name, task)
 
-        self.task = task
+        self.name_ = UniqueNameField(app, "name", BrokerGroup) # XXX
+        self.add_field(self.name_)
 
-        self.group_name = UniqueNameField(app, "name", BrokerGroup)
-        self.add_field(self.group_name)
+        self.description = self.Description(app, "description")
+        self.add_field(self.description)
 
+    class Description(MultilineStringField):
+        def render_title(self, session):
+            return "Description"
+
+class BrokerGroupAdd(ObjectTask):
+    def __init__(self, app, frame):
+        super(BrokerGroupAdd, self).__init__(app, frame)
+
+        self.form = BrokerGroupAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add broker group"
+
+    def do_invoke(self, invoc, obj, name, description):
+        conn = self.app.model.get_sql_connection()
+        cursor = conn.cursor()
+
+        group = self.cls.create_object(cursor)
+        group.name = name
+        group.description = description
+
+        group.fake_qmf_values()
+
+        try:
+            group.save(cursor)
+        finally:
+            cursor.close()
+
+        conn.commit()
+
+        invoc.end()
+
+        return group
+
 class BrokerGroupAddForm(BrokerGroupForm):
     def process_submit(self, session):
         self.validate(session)
 
         if not self.errors.get(session):
-            name = self.group_name.get(session)
+            name = self.name_.get(session)
             description = ""
 
             self.task.invoke(session, None, name, description)
-            self.task.exit_with_redirect(session, None)
+            self.task.exit_with_redirect(session)
 
     def render_title(self, session):
         return self.task.get_title(session, None)
 
-class BrokerGroupEditForm(BrokerGroupForm):
-    def __init__(self, app, name, task):
-        super(BrokerGroupEditForm, self).__init__(app, name, task)
+class BrokerGroupEdit(ObjectTask):
+    def __init__(self, app, frame):
+        super(BrokerGroupEdit, self).__init__(app, frame)
 
-        self.group = NewBrokerGroupParameter(app, "group")
-        self.add_parameter(self.group)
+        self.form = BrokerGroupEditForm(app, self.name, self)
 
+    def get_title(self, session):
+        return "Edit"
+
+    def do_invoke(self, invoc, group, name, description):
+        assert group
+
+        group.name = name
+        group.description = description
+
+        conn = self.app.model.get_sql_connection()
+        cursor = conn.cursor()
+
+        try:
+            group.save(cursor)
+        finally:
+            cursor.close()
+
+        conn.commit()
+
+        invoc.end()
+
+class BrokerGroupEditForm(BrokerGroupForm):
     def process_submit(self, session):
         self.validate(session)
 
         if not self.errors.get(session):
-            group = self.group.get(session)
-            name = self.group_name.get(session)
+            group = self.object.get(session)
+            name = self.name_.get(session)
+            description = self.description.get(session)
 
-            self.task.invoke(session, group, name)
-            self.task.exit_with_redirect(session, group)
+            self.task.invoke(session, group, name, description)
+            self.task.exit_with_redirect(session)
 
     def process_display(self, session):
-        group = self.group.get(session)
-        self.group_name.set(session, group.name)
+        group = self.object.get(session)
 
+        self.name_.set(session, group.name)
+        self.description.set(session, group.description)
+
     def render_title(self, session):
-        group = self.group.get(session)
-        return self.task.get_description(session, group)
+        group = self.object.get(session)
+        return self.task.get_description(session)
+
+class BrokerGroupRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_exit(self, session):
+        self.app.main_page.main.messaging.view.show(session)
+
+    def do_invoke(self, invoc, group):
+        conn = self.app.model.get_sql_connection()
+        cursor = conn.cursor()
+
+        try:
+            group.delete(cursor)
+        finally:
+            cursor.close()
+
+        conn.commit()
+
+        invoc.end()
+
+class BrokerEngroup(ObjectTask):
+    def get_title(self, session):
+        return "Add to groups"
+
+    def do_invoke(self, invoc, broker, groups):
+        print "XXX engroup", broker, groups
+
+        invoc.end()
+
+        return
+
+        all_groups = BrokerGroup.select()
+        selected_ids = [x.id for x in selected_groups]
+        for group in all_groups:
+            sql_sel = "broker_id=%i and broker_group_id=%i" % \
+                (broker.id, group.id)
+            existing_mapping = BrokerGroupMapping.select(sql_sel)
+            if not group.id in selected_ids:
+                if existing_mapping.count() > 0:
+                    # remove mapping if group is not checked and there
+                    # is already a mapping
+                    existing_mapping[0].destroySelf()
+            else:
+                if existing_mapping.count() == 0:
+                    # add mapping if group is checked but there
+                    # is not already a mapping
+                    new_mapping = BrokerGroupMapping(brokerID=broker.id,
+                                                     brokerGroupID=group.id)
+                    new_mapping.syncUpdate()

Modified: mgmt/newdata/cumin/python/cumin/messaging/brokerlink.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/brokerlink.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/brokerlink.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -2,6 +2,9 @@
 
 from mint import *
 from wooly import *
+from cumin.objectframe import *
+from cumin.objectselector import *
+from cumin.objecttask import *
 from wooly.widgets import *
 from cumin.widgets import *
 from cumin.parameters import *
@@ -15,6 +18,27 @@
 
 strings = StringCatalog(__file__)
 
+class BrokerLinkFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Link
+
+        super(BrokerLinkFrame, self).__init__(app, name, cls)
+
+        self.view.add_tab(RouteSelector(app, "routes", self.object))
+
+        self.route_add = RouteAdd(app, self)
+        self.remove = BrokerLinkRemove(app, self)
+
+class BrokerLinkRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_exit(self, session):
+        self.app.main_page.main.messaging.broker.view.show(session)
+
+    def do_invoke(self, invoc, link):
+        self.qmf_call(invoc, link, "remove")
+
 class BrokerLinkSelector(ObjectSelector):
     def __init__(self, app, name, vhost):
         cls = app.rosemary.org_apache_qpid_broker.Link
@@ -34,20 +58,17 @@
         self.add_attribute_column(cls.transport)
         self.add_attribute_column(cls.durable)
 
-        self.add_task(app.messaging.BrokerLinkAdd, self.vhost)
-        self.add_selection_task(app.messaging.BrokerLinkRemove)
+        self.remove = BrokerLinkSelectionRemove(app, self)
 
     # Address column XXX
 
-class BrokerLinkFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.org_apache_qpid_broker.Link
+class BrokerLinkSelectionRemove(SelectionTask):
+    def get_title(self, session):
+        return "Remove"
 
-        super(BrokerLinkFrame, self).__init__(app, name, cls)
+    def do_invoke(self, invoc, link):
+        self.qmf_call(invoc, link, "remove")
 
-        routes = RouteSelector(app, "routes", self.object)
-        self.view.add_tab(routes)
-
 class RouteSelector(ObjectSelector):
     def __init__(self, app, name, link):
         cls = app.rosemary.org_apache_qpid_broker.Bridge
@@ -64,11 +85,27 @@
         self.add_attribute_column(cls.tag)
         self.add_attribute_column(cls.excludes)
 
-        self.add_task(app.messaging.RouteAdd, self.link)
-        self.add_selection_task(app.messaging.RouteRemove)
+        self.remove = RouteSelectionRemove(app, self)
 
+class RouteSelectionRemove(SelectionTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_invoke(self, invoc, route):
+        self.qmf_call(invoc, route, "close")
+
 # XXX RouteFrame
 
+class RouteRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_exit(self, session):
+        self.app.main_page.main.messaging.broker.view.show(session)
+
+    def do_invoke(self, invoc, route):
+        self.qmf_call(invoc, route, "close")
+
 class LinkView(CuminView):
     def __init__(self, app, name, link):
         super(LinkView, self).__init__(app, name, link)
@@ -78,9 +115,7 @@
 
         #self.tabs.add_tab(LinkStats(app, "stats"))
 
-        self.routes = RouteSet(app, "routes", link)
-        self.tabs.add_tab(self.routes)
-
+        self.tabs.add_tab(RouteSet(app, "routes", link))
         self.tabs.add_tab(CuminDetails(app, "details", link))
 
 class LinkGeneralStatSet(StatSet):
@@ -172,12 +207,25 @@
     def render_title(self, session):
         return "Choose an Exchange"
 
-class RouteAddForm(FieldSubmitForm):
+class RouteAdd(ObjectTask):
+    def __init__(self, app, frame):
+        super(RouteAdd, self).__init__(app, frame)
+
+        self.form = RouteAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add route"
+
+    def do_invoke(self, invoc, link, exchange, key, tag, dynamic, sync,
+                  excludes):
+        self.qmf_call(invoc, link, "bridge",
+                      link.durable, exchange.name, exchange.name,
+                      key, tag, excludes, False, False, dynamic, sync)
+
+class RouteAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
-        super(RouteAddForm, self).__init__(app, name)
+        super(RouteAddForm, self).__init__(app, name, task)
 
-        self.task = task
-
         self.link = LinkParameter(app, "link")
         self.add_parameter(self.link)
 
@@ -266,7 +314,7 @@
 
             self.task.invoke(session, link, exchange, key, tag,
                              dynamic, sync, excludes)
-            self.task.exit_with_redirect(session, link)
+            self.task.exit_with_redirect(session)
 
     def render_title(self, session):
         link = self.link.get(session)
@@ -281,6 +329,27 @@
         self.object = ListParameter(app, "route", item)
         self.add_parameter(self.object)
 
+class BrokerLinkAdd(ObjectTask):
+    def __init__(self, app, frame):
+        super(BrokerLinkAdd, self).__init__(app, frame)
+
+        self.form = BrokerLinkAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add broker link"
+
+    def do_invoke(self, invoc, vhost, host, port, durable, username,
+                  password, transport):
+        broker = vhost.broker # XXX
+
+        if username == "anonymous":
+            mech = "ANONYMOUS"
+        else:
+            mech = "PLAIN"
+
+        self.qmf_call(invoc, broker, "connect",
+                      host, port, durable, mech, username, password, transport)
+
 class BrokerLinkAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
         super(BrokerLinkAddForm, self).__init__(app, name, task)
@@ -323,7 +392,7 @@
 
             self.task.invoke(session, vhost, host, port,
                              durable, username, password, transport)
-            self.task.exit_with_redirect(session, vhost)
+            self.task.exit_with_redirect(session)
 
     class Host(NameField):
         def render_title(self, session):

Modified: mgmt/newdata/cumin/python/cumin/messaging/connection.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/connection.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/connection.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,9 +1,10 @@
 from wooly import *
 from wooly.widgets import *
 from wooly.tables import *
-from datetime import datetime
+
 from cumin.objectframe import *
 from cumin.objectselector import *
+from cumin.objecttask import *
 from cumin.stat import *
 from cumin.widgets import *
 from cumin.parameters import *
@@ -14,6 +15,43 @@
 
 strings = StringCatalog(__file__)
 
+class ConnectionFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Connection
+
+        super(ConnectionFrame, self).__init__(app, name, cls)
+
+        self.icon_href = "resource?name=client-36.png"
+
+        self.session = SessionFrame(app, "session")
+        self.add_mode(self.session)
+
+        self.overview = ConnectionOverview(app, "overview", self.object)
+        self.view.add_tab(self.overview)
+
+        self.view.add_tab(SessionSelector(app, "sessions", self.object))
+
+        self.close = ConnectionClose(app, self)
+
+class ConnectionClose(ObjectTask):
+    def get_title(self, session):
+        return "Close"
+
+    def do_invoke(self, invoc, conn):
+        # XXX generalize this check and use it for other closes
+
+        session_ids = set()
+
+        for broker in self.app.model.mint.model.qmf_brokers:
+            session_ids.add(broker.getSessionId())
+
+        for sess in conn.sessions:
+            if sess.name in session_ids:
+                raise Exception \
+                    ("Cannot close management connection %s" % conn.address)
+
+        self.qmf_call(invoc, conn, "close")
+
 class ConnectionSelector(ObjectSelector):
     def __init__(self, app, name, vhost):
         cls = app.rosemary.org_apache_qpid_broker.Connection
@@ -36,6 +74,27 @@
         self.add_attribute_column(cls.bytesFromClient)
         self.add_attribute_column(cls.bytesToClient)
 
+        self.close = ConnectionSelectionClose(app, self)
+
+class ConnectionSelectionClose(SelectionTask):
+    def get_title(self, session):
+        return "Close"
+
+    def do_invoke(self, invoc, conn):
+        # XXX generalize this check and use it for other closes
+
+        session_ids = set()
+
+        for broker in self.app.model.mint.model.qmf_brokers:
+            session_ids.add(broker.getSessionId())
+
+        for sess in conn.sessions:
+            if sess.name in session_ids:
+                raise Exception \
+                    ("Cannot close management connection %s" % conn.address)
+
+        self.qmf_call(invoc, conn, "close")
+
 class ConnectionProcessColumn(ObjectAttributeColumn):
     def __init__(self, app, name, attr, pid_attr):
         super(ConnectionProcessColumn, self).__init__(app, name, attr)
@@ -57,31 +116,6 @@
         args = (record[self.field.index], record[self.pid_field.index])
         return "%s (%i)" % args
 
-class ConnectionFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.org_apache_qpid_broker.Connection
-
-        super(ConnectionFrame, self).__init__(app, name, cls)
-
-        self.icon_href = "resource?name=client-36.png"
-
-        self.overview = ConnectionStats(app, "overview", self.object)
-        self.view.add_tab(self.overview)
-
-class ConnectionView(CuminView):
-    def __init__(self, app, name, conn):
-        super(ConnectionView, self).__init__(app, name, conn)
-
-        self.tabs = TabbedModeSet(app, "tabs")
-        self.add_child(self.tabs)
-
-        self.tabs.add_tab(ConnectionStats(app, "stats", conn))
-
-        self.sessions = SessionSet(app, "sessions", conn)
-        self.tabs.add_tab(self.sessions)
-
-        self.tabs.add_tab(CuminDetails(app, "details", conn))
-
 class ConnectionGeneralStatSet(StatSet):
     def __init__(self, app, name, object):
         super(ConnectionGeneralStatSet, self).__init__(app, name, object)
@@ -95,9 +129,9 @@
         self.attrs = ("bytesFromClient", "bytesToClient",
                        "framesFromClient", "framesToClient")
 
-class ConnectionStats(Widget):
+class ConnectionOverview(Widget):
     def __init__(self, app, name, conn):
-        super(ConnectionStats, self).__init__(app, name)
+        super(ConnectionOverview, self).__init__(app, name)
 
         self.add_child(ConnectionIOStatSet(app, "io", conn))
         self.add_child(ConnectionGeneralStatSet(app, "general", conn))
@@ -113,3 +147,60 @@
     class SendReceiveRateChart(StatFlashChart):
         def render_title(self, session):
             return "Bytes sent and received"
+
+class SessionFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Session
+
+        super(SessionFrame, self).__init__(app, name, cls)
+
+        self.close = SessionClose(app, self)
+        self.detach = SessionDetach(app, self)
+
+class SessionClose(ObjectTask):
+    def get_title(self, session):
+        return "Close"
+
+    def do_invoke(self, invoc, sess):
+        self.qmf_call(invoc, sess, "close")
+
+class SessionDetach(ObjectTask):
+    def get_title(self, session):
+        return "Detach"
+
+    def do_invoke(self, invoc, sess):
+        self.qmf_call(invoc, sess, "detach")
+
+class SessionSelector(ObjectSelector):
+    def __init__(self, app, name, conn):
+        cls = app.rosemary.org_apache_qpid_broker.Session
+
+        super(SessionSelector, self).__init__(app, name, cls)
+
+        self.conn = conn
+
+        frame = "main.messaging.broker.connection.session"
+        col = ObjectLinkColumn(app, "name", cls.name, cls._id, frame)
+        self.add_column(col)
+
+        self.add_attribute_column(cls.attached)
+        self.add_attribute_column(cls.detachedLifespan)
+        self.add_attribute_column(cls.framesOutstanding)
+        self.add_attribute_column(cls.clientCredit)
+
+        self.close = SessionSelectionClose(app, self)
+        self.detach = SessionSelectionDetach(app, self)
+
+class SessionSelectionClose(SelectionTask):
+    def get_title(self, session):
+        return "Close"
+
+    def do_invoke(self, invoc, sess):
+        self.qmf_call(invoc, sess, "close")
+
+class SessionSelectionDetach(SelectionTask):
+    def get_title(self, session):
+        return "Detach"
+
+    def do_invoke(self, invoc, sess):
+        self.qmf_call(invoc, sess, "detach")

Modified: mgmt/newdata/cumin/python/cumin/messaging/connection.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/connection.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/connection.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,4 +1,4 @@
-[ConnectionStats.html]
+[ConnectionOverview.html]
 <table class="twocol">
   <tbody>
   <tr>

Modified: mgmt/newdata/cumin/python/cumin/messaging/exchange.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/exchange.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/exchange.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -18,6 +18,44 @@
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.messaging.exchange")
 
+class ExchangeFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Exchange
+
+        super(ExchangeFrame, self).__init__(app, name, cls)
+
+        self.icon_href = "resource?name=exchange-36.png"
+
+        self.overview = ExchangeOverview(app, "overview", self.object)
+        self.view.add_tab(self.overview)
+
+        self.bindings = ExchangeBindingSelector(app, "bindings", self.object)
+        self.view.add_tab(self.bindings)
+
+        self.remove = ExchangeRemove(app, self)
+
+    def get_title(self, session):
+        title = super(ExchangeFrame, self).get_title(session)
+
+        if title == "":
+            title = "Default exchange"
+
+        return title
+
+class ExchangeRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_exit(self, session):
+        self.app.main_page.main.messaging.broker.view.show(session)
+
+    def do_invoke(self, invoc, exchange):
+        session = self.app.model.get_session_by_object(exchange)
+        session.exchange_delete(exchange=exchange.name)
+        session.sync()
+
+        invoc.end()
+
 class ExchangeSelector(ObjectSelector):
     def __init__(self, app, name, vhost):
         cls = app.rosemary.org_apache_qpid_broker.Exchange
@@ -37,34 +75,19 @@
     
         self.add_reference_filter(vhost, cls.vhostRef)
 
-        self.add_task(app.messaging.ExchangeAdd, self.vhost)
-        self.add_selection_task(app.messaging.ExchangeRemove)
+        self.remove = ExchangeSelectionRemove(app, self)
 
-class ExchangeFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.org_apache_qpid_broker.Exchange
+class ExchangeSelectionRemove(SelectionTask):
+    def get_title(self, session):
+        return "Remove"
 
-        super(ExchangeFrame, self).__init__(app, name, cls)
+    def do_invoke(self, invoc, exchange):
+        session = self.app.model.get_session_by_object(exchange)
+        session.exchange_delete(exchange=exchange.name)
+        session.sync()
 
-        self.icon_href = "resource?name=exchange-36.png"
+        invoc.end()
 
-        self.overview = ExchangeOverview(app, "overview", self.object)
-        self.view.add_tab(self.overview)
-
-        self.bindings = ExchangeBindingSelector(app, "bindings", self.object)
-        self.view.add_tab(self.bindings)
-
-        # XXX self.add_summary_task(main.module.exchange_remove)
-
-    def render_title(self, session):
-        exchange = self.object.get(session)
-
-        if exchange:
-            if exchange.name:
-                return super(ExchangeFrame, self).render_title(session)
-            else:
-                return "Default exchange"
-
 class ExchangeBindingSelector(BindingSelector):
     def __init__(self, app, name, exchange):
         super(ExchangeBindingSelector, self).__init__(app, name)
@@ -194,6 +217,34 @@
     def render_title(self, session):
         return "Advanced options"
 
+class ExchangeAdd(ObjectTask):
+    MSG_SEQUENCE = "qpid.msg_sequence"
+    IVE = "qpid.ive"
+
+    def __init__(self, app, frame):
+        super(ExchangeAdd, self).__init__(app, frame)
+
+        self.form = ExchangeAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add exchange"
+
+    def do_invoke(self, invoc, vhost, name, type, durable, sequence, ive):
+        args = dict()
+
+        if sequence:
+            args[self.MSG_SEQUENCE] = 1
+
+        if ive:
+            args[self.IVE] = 1
+
+        session = self.app.model.get_session_by_object(vhost)
+        session.exchange_declare \
+            (exchange=name, type=type, durable=durable, arguments=args)
+        session.sync()
+
+        invoc.end()
+
 class ExchangeAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
         super(ExchangeAddForm, self).__init__(app, name, task)
@@ -226,7 +277,7 @@
 
             self.task.invoke(session, vhost, name, type,
                              durable, sequence_numbers, initial_value)
-            self.task.exit_with_redirect(session, vhost)
+            self.task.exit_with_redirect(session)
 
 class ExchangeGeneralStatSet(StatSet):
     def __init__(self, app, name, object):
@@ -272,4 +323,5 @@
 
     @classmethod
     def get_builtins(cls):
-        return ["", "amq.direct", "amq.topic", "amq.match", "amq.fanout", "qpid.management"]
+        return ["", "amq.direct", "amq.topic", "amq.match",
+                "amq.fanout", "qpid.management"]

Modified: mgmt/newdata/cumin/python/cumin/messaging/main.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/main.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/main.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -7,7 +7,6 @@
 
 from broker import *
 from brokergroup import *
-from model import *
 from test import *
 
 strings = StringCatalog(__file__)
@@ -16,71 +15,11 @@
     def __init__(self, app, name):
         super(Module, self).__init__(app, name)
 
-        cls = app.rosemary.org_apache_qpid_broker.Broker
+        self.frame = MessagingFrame(self.app, "messaging")
 
-        BrokerEngroup(self, cls)
-        ExchangeAdd(self, cls)
-        BrokerLinkAdd(self, cls)
-        QueueAdd(self, cls)
-
-        cls = app.rosemary.com_redhat_cumin.BrokerGroup
-
-        BrokerGroupAdd(self, cls)
-        BrokerGroupEdit(self, cls)
-
-        task = BrokerGroupRemove(self, cls)
-        SelectionTask(task)
-
-        cls = app.rosemary.org_apache_qpid_broker.Queue
-
-        task = QueueRemove(self, cls)
-        SelectionTask(task)
-
-        task = QueuePurge(self, cls)
-        SelectionTask(task)
-
-        BindingAdd(self, cls)
-        MoveMessages(self, cls)
-
-        cls = app.rosemary.org_apache_qpid_broker.Exchange
-
-        task = ExchangeRemove(self, cls)
-        SelectionTask(task)
-
-        cls = app.rosemary.org_apache_qpid_broker.Binding
-
-        task = BindingRemove(self, cls)
-        SelectionTask(task)
-
-        cls = app.rosemary.org_apache_qpid_broker.Link
-
-        task = BrokerLinkRemove(self, cls)
-        SelectionTask(task)
-
-        RouteAdd(self, cls)
-
-        cls = app.rosemary.org_apache_qpid_broker.Bridge
-
-        task = RouteRemove(self, cls)
-        SelectionTask(task)
-
-        cls = app.rosemary.org_apache_qpid_broker.Connection
-
-        task = ConnectionClose(self, cls)
-        SelectionTask(task)
-
-        cls = app.rosemary.org_apache_qpid_broker.Session
-
-        task = SessionDetach(self, cls)
-        SelectionTask(task)
-
-        task = SessionClose(self, cls)
-        SelectionTask(task)
-
     def init(self):
         super(Module, self).init()
 
-        self.frame = MessagingFrame(self.app, "messaging")
         self.app.main_page.main.messaging = self.frame
         self.app.main_page.main.add_tab(self.frame)
 
@@ -98,8 +37,8 @@
         self.add_mode(self.broker)
         self.add_sticky_view(self.broker)
 
-        self.broker_group = BrokerGroupFrame(app, "brokergroup")
-        self.add_mode(self.broker_group)
+        self.brokergroup = BrokerGroupFrame(app, "brokergroup")
+        self.add_mode(self.brokergroup)
 
     def render_title(self, session):
         return "Messaging"

Deleted: mgmt/newdata/cumin/python/cumin/messaging/model.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/model.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/model.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,330 +0,0 @@
-from wooly import Session
-
-from cumin.model import *
-from cumin.objecttask import *
-from cumin.util import *
-
-from broker import *
-from brokergroup import *
-from brokerlink import *
-from queue import *
-from exchange import *
-
-class ConnectionClose(ObjectTask):
-    def get_title(self, session, conn):
-        return "Close"
-
-    def do_invoke(self, invoc, conn):
-        # XXX generalize this check and use it for other closes
-
-        session_ids = set()
-
-        for broker in self.app.model.mint.model.qmf_brokers:
-            session_ids.add(broker.getSessionId())
-
-        for sess in conn.sessions:
-            if sess.name in session_ids:
-                raise Exception \
-                    ("Cannot close management connection %s" % conn.address)
-
-        print "XXX conn.close", conn
-
-        invoc.end()
-
-class SessionDetach(ObjectTask):
-    def get_title(self, session, sess):
-        return "Detach"
-
-    def do_invoke(self, invoc, sess):
-        self.qmf_call(invoc, sess, "detach")
-
-class SessionClose(ObjectTask):
-    def get_title(self, session, sess):
-        return "Close"
-
-    def do_invoke(self, invoc, sess):
-        self.qmf_call(invoc, sess, "close")
-
-class QueueAdd(ObjectTask):
-    def __init__(self, module, cls):
-        super(QueueAdd, self).__init__(module, cls)
-
-        self.form = QueueAddForm(self.app, self.name, self)
-
-    def get_title(self, session, vhost):
-        return "Add queue"
-
-class QueueRemove(ObjectTask):
-    def get_title(self, session, queue):
-        return "Remove"
-
-    def do_exit(self, session, queue):
-        self.app.main_page.main.messaging.broker.view.show(session)
-
-    def do_invoke(self, invoc, queue):
-        session = self.app.model.get_session_by_object(queue)
-        session.queue_delete(queue=queue.name)
-        session.sync()
-
-        invoc.end()
-
-class QueuePurge(ObjectTask):
-    def __init__(self, module, cls):
-        super(QueuePurge, self).__init__(module, cls)
-
-        self.form = QueuePurgeForm(self.app, self.name, self)
-
-    def get_title(self, session, queue):
-        return "Purge"
-
-    def do_invoke(self, invoc, queue, count=0):
-        self.qmf_call(invoc, queue, "purge", count)
-
-class BindingAdd(ObjectTask):
-    def __init__(self, module, cls):
-        super(BindingAdd, self).__init__(module, cls)
-
-        self.form = BindingAddForm(self.app, self.name, self)
-
-    def get_title(self, session, vhost):
-        return "Add binding"
-
-    def do_invoke(self, invoc, vhost, queue, exchange, binding_key, args):
-        session = self.app.model.get_session_by_object(vhost)
-        session.exchange_bind(queue=queue.name, exchange=exchange.name,
-                              binding_key=binding_key, arguments=args)
-        session.sync()
-
-        invoc.end()
-
-class BindingRemove(ObjectTask):
-    def get_title(self, session, binding):
-        return "Remove"
-
-    def do_invoke(self, invoc, binding):
-        assert isinstance(binding, Binding)
-
-        session = self.app.model.get_session_by_object(binding)
-        session.exchange_unbind(queue=binding.queue.name,
-                                exchange=binding.exchange.name,
-                                binding_key=binding.bindingKey)
-        session.sync()
-
-        invoc.end()
-
-class MoveMessages(ObjectTask):
-    def __init__(self, module, cls):
-        super(MoveMessages, self).__init__(module, cls)
-
-        self.form = MoveMessagesForm(self.app, self.name, self)
-
-    def get_title(self, session, vhost):
-        return "Move messages"
-
-    def do_invoke(self, invoc, vhost, src, dst, count):
-        broker = vhost.broker
-        broker.queueMoveMessages(completion, src.name, dst.name, count)
-
-class ExchangeAdd(ObjectTask):
-    MSG_SEQUENCE = "qpid.msg_sequence"
-    IVE = "qpid.ive"
-
-    def __init__(self, module, cls):
-        super(ExchangeAdd, self).__init__(module, cls)
-
-        self.form = ExchangeAddForm(self.app, self.name, self)
-
-    def get_title(self, session, vhost):
-        return "Add exchange"
-
-    def do_invoke(self, invoc, vhost, name, type, durable, sequence, ive):
-        args = dict()
-
-        if sequence:
-            args[self.MSG_SEQUENCE] = 1
-
-        if ive:
-            args[self.IVE] = 1
-
-        session = self.app.model.get_session_by_object(vhost)
-        session.exchange_declare \
-            (exchange=name, type=type, durable=durable, arguments=args)
-        session.sync()
-
-        invoc.end()
-
-class ExchangeRemove(ObjectTask):
-    def get_title(self, session, exchange):
-        return "Remove"
-
-    def do_exit(self, session, exchange):
-        self.app.main_page.main.messaging.broker.view.show(session)
-
-    def do_invoke(self, invoc, exchange):
-        session = self.app.model.get_session_by_object(exchange)
-        session.exchange_delete(exchange=exchange.name)
-        session.sync()
-
-        invoc.end()
-
-class BrokerLinkAdd(ObjectTask):
-    def __init__(self, module, cls):
-        super(BrokerLinkAdd, self).__init__(module, cls)
-
-        self.form = BrokerLinkAddForm(self.app, self.name, self)
-
-    def get_title(self, session, vhost):
-        return "Add broker link"
-
-    def do_invoke(self, invoc, vhost, host, port, durable, username,
-                    password, transport):
-        broker = vhost.broker # XXX
-
-        if username == "anonymous":
-            mech = "ANONYMOUS"
-        else:
-            mech = "PLAIN"
-
-        self.qmf_call(invoc, broker, "connect",
-                      host, port, durable, mech, username, password, transport)
-
-class BrokerLinkRemove(ObjectTask):
-    def get_title(self, session, link):
-        return "Remove"
-
-    def do_exit(self, session, link):
-        self.app.main_page.main.messaging.broker.view.show(session)
-
-    def do_invoke(self, invoc, link):
-        self.qmf_call(invoc, link, "remove")
-
-class RouteAdd(ObjectTask):
-    def __init__(self, module, cls):
-        super(RouteAdd, self).__init__(module, cls)
-
-        self.form = RouteAddForm(self.app, self.name, self)
-
-    def get_title(self, session, link):
-        return "Add route"
-
-    def do_invoke(self, invoc, link, exchange, key, tag, dynamic, sync,
-                    excludes):
-        self.qmf_call(invoc, link, "bridge",
-                      link.durable, exchange.name, exchange.name,
-                      key, tag, excludes, False, False, dynamic, sync)
-
-class RouteRemove(ObjectTask):
-    def get_title(self, session, route):
-        return "Remove"
-
-    def do_exit(self, session, route):
-        self.app.main_page.main.messaging.broker.view.show(session)
-
-    def do_invoke(self, invoc, route):
-        self.qmf_call(invoc, "close")
-
-class BrokerGroupAdd(ObjectTask):
-    def __init__(self, module, cls):
-        super(BrokerGroupAdd, self).__init__(module, cls)
-
-        self.form = BrokerGroupAddForm(self.app, self.name, self)
-
-    def get_title(self, session, obj):
-        return "Add broker group"
-
-    def do_invoke(self, invoc, obj, name, description):
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
-
-        group = self.cls.create_object(cursor)
-        group.name = name
-        group.description = description
-
-        group.fake_qmf_values()
-
-        try:
-            group.save(cursor)
-        finally:
-            cursor.close()
-
-        conn.commit()
-
-        invoc.end()
-
-        return group
-
-class BrokerGroupEdit(ObjectTask):
-    def __init__(self, module, cls):
-        super(BrokerGroupEdit, self).__init__(module, cls)
-
-        self.form = BrokerGroupEditForm(self.app, self.name, self)
-
-    def get_title(self, session, group):
-        return "Edit"
-
-    def do_invoke(self, invoc, group, name, description):
-        assert group
-
-        group.name = name
-
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
-
-        try:
-            group.save(cursor)
-        finally:
-            cursor.close()
-
-        conn.commit()
-
-        invoc.end()
-
-class BrokerGroupRemove(ObjectTask):
-    def get_title(self, session, group):
-        return "Remove"
-
-    def do_exit(self, session, group):
-        self.app.main_page.main.messaging.view.show(session)
-
-    def do_invoke(self, invoc, group):
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
-
-        try:
-            group.delete(cursor)
-        finally:
-            cursor.close()
-
-        conn.commit()
-
-        invoc.end()
-
-class BrokerEngroup(ObjectTask):
-    def get_title(self, session, broker):
-        return "Add to groups"
-
-    def do_invoke(self, invoc, broker, groups):
-        print "XXX engroup", broker, groups
-
-        invoc.end()
-
-        return
-
-        all_groups = BrokerGroup.select()
-        selected_ids = [x.id for x in selected_groups]
-        for group in all_groups:
-            sql_sel = "broker_id=%i and broker_group_id=%i" % \
-                (broker.id, group.id)
-            existing_mapping = BrokerGroupMapping.select(sql_sel)
-            if not group.id in selected_ids:
-                if existing_mapping.count() > 0:
-                    # remove mapping if group is not checked and there
-                    # is already a mapping
-                    existing_mapping[0].destroySelf()
-            else:
-                if existing_mapping.count() == 0:
-                    # add mapping if group is checked but there
-                    # is not already a mapping
-                    new_mapping = BrokerGroupMapping(brokerID=broker.id,
-                                                     brokerGroupID=group.id)
-                    new_mapping.syncUpdate()

Modified: mgmt/newdata/cumin/python/cumin/messaging/queue.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/messaging/queue.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/messaging/queue.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -11,7 +11,6 @@
 from cumin.parameters import *
 from cumin.sqladapter import *
 from cumin.stat import *
-from cumin.table import *
 from cumin.util import *
 from cumin.widgets import *
 
@@ -22,6 +21,44 @@
 strings = StringCatalog(__file__)
 log = logging.getLogger("cumin.messaging.queue")
 
+class QueueFrame(ObjectFrame):
+    def __init__(self, app, name):
+        cls = app.rosemary.org_apache_qpid_broker.Queue
+
+        super(QueueFrame, self).__init__(app, name, cls)
+
+        self.icon_href = "resource?name=queue-36.png"
+
+        self.overview = QueueOverview(app, "overview", self.object)
+        self.view.add_tab(self.overview)
+
+        self.bindings = QueueBindingSelector(app, "bindings", self.object)
+        self.view.add_tab(self.bindings)
+
+        self.subscriptions = SubscriptionSelector \
+            (app, "subscriptions", self.object)
+        self.view.add_tab(self.subscriptions)
+
+        self.subscription = SubscriptionFrame(app, "subscription")
+        self.add_mode(self.subscription)
+
+        self.remove = QueueRemove(app, self)
+        self.purge = QueuePurge(app, self)
+
+class QueueRemove(ObjectTask):
+    def get_title(self, session):
+        return "Remove"
+
+    def do_exit(self, session, queue):
+        self.app.main_page.main.messaging.broker.view.show(session)
+
+    def do_invoke(self, invoc, queue):
+        session = self.app.model.get_session_by_object(queue)
+        session.queue_delete(queue=queue.name)
+        session.sync()
+
+        invoc.end()
+
 class QueueSelector(ObjectSelector):
     def __init__(self, app, name, vhost):
         cls = app.rosemary.org_apache_qpid_broker.Queue
@@ -41,31 +78,27 @@
 
         self.add_reference_filter(vhost, cls.vhostRef)
 
-        self.add_task(app.messaging.QueueAdd, self.vhost)
-        self.add_selection_task(app.messaging.QueuePurge)
-        self.add_selection_task(app.messaging.QueueRemove)
+        self.remove = QueueSelectionRemove(app, self)
+        self.purge = QueueSelectionPurge(app, self)
 
-class QueueFrame(ObjectFrame):
-    def __init__(self, app, name):
-        cls = app.rosemary.org_apache_qpid_broker.Queue
+class QueueSelectionRemove(SelectionTask):
+    def get_title(self, session):
+        return "Remove"
 
-        super(QueueFrame, self).__init__(app, name, cls)
+    def do_invoke(self, invoc, queue):
+        session = self.app.model.get_session_by_object(queue)
+        session.queue_delete(queue=queue.name)
+        session.sync()
 
-        self.icon_href = "resource?name=queue-36.png"
+        invoc.end()
 
-        self.overview = QueueStats(app, "overview", self.object)
-        self.view.add_tab(self.overview)
+class QueueSelectionPurge(SelectionTask):
+    def get_title(self, session):
+        return "Purge"
 
-        self.bindings = QueueBindingSelector(app, "bindings", self.object)
-        self.view.add_tab(self.bindings)
+    def do_invoke(self, invoc, queue, count=0):
+        self.qmf_call(invoc, queue, "purge", count)
 
-        self.subscriptions = SubscriptionSelector \
-            (app, "subscriptions", self.object)
-        self.view.add_tab(self.subscriptions)
-
-        self.subscription = SubscriptionFrame(app, "subscription")
-        self.add_mode(self.subscription)
-
 class QueueBindingSelector(BindingSelector):
     def __init__(self, app, name, queue):
         super(QueueBindingSelector, self).__init__(app, name)
@@ -76,6 +109,15 @@
 
         self.queue_column.visible = False
 
+class QueueAdd(ObjectTask):
+    def __init__(self, app, frame):
+        super(QueueAdd, self).__init__(app, frame)
+
+        self.form = QueueAddForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Add queue"
+
 class QueueAddForm(ObjectTaskForm):
     def __init__(self, app, name, task):
         super(QueueAddForm, self).__init__(app, name, task)
@@ -334,6 +376,18 @@
 
             self.process_return(session)
 
+class QueuePurge(ObjectTask):
+    def __init__(self, app, frame):
+        super(QueuePurge, self).__init__(app, frame)
+
+        self.form = QueuePurgeForm(app, self.name, self)
+
+    def get_title(self, session):
+        return "Purge"
+
+    def do_invoke(self, invoc, queue, count=0):
+        self.qmf_call(invoc, queue, "purge", count)
+
 class QueuePurgeForm(ObjectTaskForm):
     def __init__(self, app, name, task):
         super(QueuePurgeForm, self).__init__(app, name, task)
@@ -359,7 +413,7 @@
                 raise Exception("Wrong Value")
 
             self.task.invoke(session, queue, count)
-            self.task.exit_with_redirect(session, queue)
+            self.task.exit_with_redirect(session)
 
 class BindSummaryPropertiesField(FormField):
     def __init__(self, app, name, queue):
@@ -424,11 +478,11 @@
             print "XXX queue binding add", queue, form_binding_info
 
             #self.task.invoke(session, queue, args)
-            self.task.exit_with_redirect(session, queue)
+            self.task.exit_with_redirect(session)
 
-class QueueStats(RadioModeSet):
+class QueueOverview(RadioModeSet):
     def __init__(self, app, name, queue):
-        super(QueueStats, self).__init__(app, name)
+        super(QueueOverview, self).__init__(app, name)
 
         self.add_tab(QueueStatsGeneral(app, "gen", queue))
         self.add_tab(QueueStatsDurability(app, "dur", queue))
@@ -527,17 +581,11 @@
     class JournalAttribute(Attribute):
         def get(self, session):
             queue = self.widget.object.get(session)
-
             cls = self.app.rosemary.com_redhat_rhm_store.Journal
 
-            conn = self.app.model.get_sql_connection()
-            cursor = conn.cursor()
+            journals = cls.get_selection(session.cursor,
+                                         _queueRef_id=queue._id)
 
-            try:
-                journals = cls.get_selection(cursor, _queueRef_id=queue._id)
-            finally:
-                cursor.close()
-
             return len(journals)
 
     def render_title(self, session):
@@ -632,38 +680,3 @@
             except IndexError:
                 return None
 
-class MoveMessagesForm(FieldSubmitForm):
-    def __init__(self, app, name, task):
-        super(MoveMessagesForm, self).__init__(app, name)
-
-        self.task = task
-
-        self.queue = QueueParameter(app, "queue")
-        self.add_parameter(self.queue)
-
-        self.dest_queue = QueueSelectField(app, "dest", self)
-        self.add_field(self.dest_queue)
-
-        self.count = MultiplicityField(app, "count")
-        self.add_field(self.count)
-
-    def process_submit(self, session):
-        self.validate(session)
-
-        if not self.errors.get(session):
-            queue = self.queue.get(session)
-            dest_queue = self.dest_queue.get(session)
-            scount = self.count.get(session)
-
-            if scount == "all":
-                count = 0
-            elif scount == "top":
-                count = 1
-            elif scount == "N":
-                count = self.count.top_n.get_n_value(session)
-            else:
-                raise Exception("Wrong Value")
-
-            self.task.invoke(session, queue, dest_queue, count)
-            self.task.exit_with_redirect(session, queue)
-

Modified: mgmt/newdata/cumin/python/cumin/model.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/model.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/model.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -173,207 +173,6 @@
         finally:
             self.lock.release()
 
-class Task(object):
-    def __init__(self, app, cls):
-        self.app = app
-        self.cls = cls
-
-        self.form = None
-
-        self.aggregate = False
-        self.navigable = True
-
-        if self.cls:
-            if self.__class__ not in self.cls.tasks_by_class:
-                self.cls.add_task(self)
-
-    # make this take app? XXX
-    def init(self):
-        if self.form:
-            self.app.form_page.modes.add_mode(self.form)
-        else:
-            log.debug("Task %s has no form associated with it", self)
-
-    def get_title(self, session):
-        raise Exception("Not implemented")
-
-    def is_enabled(self, session, object):
-        return True
-
-    def get_description(self, session, object):
-        verb = self.get_title(session)
-
-        if object is None:
-            text = verb
-        else:
-            cls = self.cls.get_title(session)
-            obj = self.cls.get_object_name(object)
-            text = "%s %s '%s'" % (verb, cls, obj)
-
-        return text
-
-    def get_href(self, session, object):
-        return self.enter(session, object).marshal()
-
-    def enter(self, session, object):
-        #log.debug("Entering %s", self)
-
-        nsession = wooly.Session(self.app.form_page)
-
-        self.form.return_url.set(nsession, session.marshal())
-        self.form.show(nsession)
-
-        self.do_enter(nsession, object)
-
-        #log.info("Entered %s", self)
-
-        return nsession
-
-    def do_enter(self, session, object):
-        pass
-
-    def exit_with_redirect(self, session, object):
-        osession = self.exit(session, object)
-        self.form.page.redirect.set(session, osession.marshal())
-
-    def exit(self, session, object):
-        log.debug("Exiting %s", self)
-
-        url = self.form.return_url.get(session)
-        osession = wooly.Session.unmarshal(self.app, url)
-
-        self.do_exit(osession, object)
-
-        log.info("Exited %s", self)
-
-        return osession
-
-    def do_exit(self, session, object):
-        pass
-
-    def invoke(self, session, object, *args, **kwargs):
-        invoc = self.start(session, object)
-
-        try:
-            result = self.do_invoke(session, object, *args, **kwargs)
-
-            self.end(invoc)
-        except Exception, e:
-            self.exception(invoc, e)
-
-    def do_invoke(self, *args, **kwargs):
-        raise Exception("Not implemented")
-
-    def start(self, session, object):
-        log.debug("Starting %s", self)
-
-        now = datetime.now()
-        subject = None
-
-        login = session.client_session.attributes["login_session"]
-
-        invoc = TaskInvocation(self, login.user, object)
-        invoc.status = invoc.PENDING
-        invoc.start_time = now
-        invoc.last_change_time = now
-
-        self.app.model.task_invocations.append(invoc)
-
-        log.info("Started %s", self)
-
-        return invoc
-
-    def end(self, invoc):
-        log.debug("Ending %s", self)
-
-        now = datetime.now()
-
-        invoc.status = invoc.OK
-        invoc.end_time = now
-        invoc.last_change_time = now
-
-        log.info("Ended %s", self)
-
-    def exception(self, invoc, e):
-        now = datetime.now()
-
-        invoc.status = invoc.FAILED
-        invoc.end_time = now
-        invoc.last_change_time = now
-        invoc.exception = e
-
-        log.exception(e)
-
-    def __str__(self):
-        return "%s.%s" % (self.__module__, self.__class__.__name__)
-
-class SetTask(Task):
-    def __init__(self, app, cls):
-        super(SetTask, self).__init__(app, cls)
-
-        self.item_task = None
-        self.aggregate = True
-
-    def init(self):
-        super(SetTask, self).init()
-
-        if not self.item_task:
-            raise Exception("Task %s has no item task" % self)
-
-    def get_title(self, session):
-        return self.item_task.get_title(session)
-
-    def get_description(self, session, objects):
-        verb = self.item_task.get_title(session)
-        cls = self.cls.get_title(session)
-        count = len(objects)
-        return "%s %i %s" % (verb, count, conjugate(cls, count))
-
-    def invoke(self, session, objects, *args, **kwargs):
-        for object in objects:
-            self.item_task.invoke(session, object, *args, **kwargs)
-
-class QmfTask(Task):
-    def invoke(self, session, object, *args, **kwargs):
-        invoc = self.start(session, object)
-
-        def completion(status_code, output_args):
-            invoc.last_change_time = datetime.now()
-
-            if status_code == 0 or status_code == "OK":
-                invoc.status = invoc.OK
-            else:
-                invoc.status = invoc.FAILED
-
-            invoc.status_code = status_code
-            invoc.output_args = output_args
-
-        try:
-            self.do_invoke(completion, session, object, *args, **kwargs)
-        except Exception, e:
-            self.exception(invoc, e)
-
-    def do_invoke(self, completion, session, object, *args, **kwargs):
-        raise Exception("Not implemented")
-
-class TaskInvocation(object):
-    PENDING = "pending"
-    FAILED = "failed"
-    OK = "ok"
-
-    def __init__(self, task, subject, object):
-        self.task = task
-        self.subject = subject
-        self.object = object
-        self.start_time = None
-        self.end_time = None
-        self.last_change_time = None
-        self.status = None
-        self.exception = None
-
-        self.status_code = None
-        self.output_args = None
-
 class CuminProperty(object):
     def __init__(self, cls, name):
         self.model = cls.model

Modified: mgmt/newdata/cumin/python/cumin/objectframe.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/objectframe.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/objectframe.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -22,13 +22,15 @@
         self.object = Attribute(app, "object")
         self.add_attribute(self.object)
 
-        self.view = ObjectView(app, name, self.object)
+        self.view = ObjectView(app, "view", self.object)
         self.add_child(self.view)
 
         self.icon_href = "resource?name=action-36.png"
 
+        self.tasks = list()
+
         self.summary_attributes = list()
-        self.summary_tasks = list()
+        self.summary_tasks = list() # XXX
 
         self.add_summary_attribute(cls._qmf_update_time)
 
@@ -37,16 +39,14 @@
 
         self.summary_attributes.append(attr)
 
-    def add_summary_task(self, task):
-        assert task not in self.summary_tasks, task
-
-        self.summary_tasks.append(task)
-
     def init(self):
         super(ObjectFrame, self).init()
 
         assert self.cls, self
 
+        for task in self.tasks:
+            task.init()
+
     def get_href(self, session, id):
         branch = session.branch()
 
@@ -67,18 +67,15 @@
 
         assert id
 
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
+        obj = self.get_object(session, id)
 
-        try:
-            obj = self.cls.get_object(cursor, id)
-        finally:
-            cursor.close()
-
         self.object.set(session, obj)
 
         super(ObjectFrame, self).do_process(session)
 
+    def get_object(self, session, id):
+        return self.cls.get_object(session.cursor, id)
+
 class ObjectAttributes(Widget):
     def __init__(self, app, name, object):
         super(ObjectAttributes, self).__init__(app, name)
@@ -111,16 +108,34 @@
     def render_value(self, session, name, value):
         return xml_escape(str(value))
 
-class ObjectTaskLinks(WidgetSet):
+class ObjectTasks(Widget):
     def __init__(self, app, name, object):
-        super(ObjectTaskLinks, self).__init__(app, name)
+        super(ObjectTasks, self).__init__(app, name)
 
         self.object = object
 
+        self.link = ObjectTasksLink(app, "link")
+        self.add_child(self.link)
+
+    def render_links(self, session):
+        writer = Writer()
+
+        for task in self.frame.tasks:
+            writer.write(self.link.render(session, task))
+
+        return writer.to_string()
+
+class ObjectTasksLink(Link):
+    def render_href(self, session, task):
+        return task.get_href(session)
+
+    def render_content(self, session, task):
+        return task.get_title(session)
+
 class SummaryAttributes(ObjectAttributes):
     pass
 
-class SummaryLinks(ObjectTaskLinks):
+class SummaryTasks(ObjectTasks):
     pass
 
 class ObjectView(Widget):
@@ -212,25 +227,13 @@
         attributes = self.Attributes(app, "attributes", self.object)
         self.add_child(attributes)
 
-        links = self.Links(app, "links", self.object)
-        self.add_child(links)
+        tasks = SummaryTasks(app, "tasks", self.object)
+        self.add_child(tasks)
 
     class Attributes(SummaryAttributes):
         def get_attributes(self, session):
             return self.frame.summary_attributes
 
-    class Links(SummaryLinks):
-        def init(self):
-            super(ObjectViewSummary.Links, self).init()
-
-            for task in self.frame.summary_tasks:
-                name = task.__class__.__name__
-                link = ObjectTaskLink(self.app, name, task, self.object)
-
-                self.add_child(link)
-
-                link.init()
-
 class ObjectDetails(Widget):
     def __init__(self, app, name, object):
         super(ObjectDetails, self).__init__(app, name)

Modified: mgmt/newdata/cumin/python/cumin/objectframe.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/objectframe.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/objectframe.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -55,9 +55,18 @@
 [ObjectAttributesEntry.html]
 <tr><th>{name}</th><td>{value}</td></tr>
 
+[ObjectTasks.html]
+<ul class="{class}">
+  {links}
+</ul>
+
+[ObjectTasksLink.html]
+<li><a href="{href}">{content}</a></li>
+
 [SummaryAttributes.css]
 div.SummaryAttributes {
     width: 20em;
+    margin: 0 0 1.5em 0;
 }
 
 div.SummaryAttributes tbody tr {
@@ -79,12 +88,12 @@
   </table>
 </div>
 
-[SummaryLinks.css]
-ul.SummaryLinks {
+[SummaryTasks.css]
+ul.SummaryTasks {
     width: 15em;
     float: right;
     list-style: none;
-    margin: 0;
+    margin: 0 0 1.5em 0;
 }
 
 [ObjectView.css]
@@ -136,7 +145,7 @@
 
 [ObjectViewSummary.html]
 <div class="{class}">
-  {links}
+  {tasks}
   {attributes}
 </div>
 

Modified: mgmt/newdata/cumin/python/cumin/objectselector.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/objectselector.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/objectselector.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -10,8 +10,6 @@
 
 strings = StringCatalog(__file__)
 
-# XXX ObjectTable
-
 class ObjectSelector(DataTable, Form):
     def __init__(self, app, name, cls, adapter=None):
         assert isinstance(cls, RosemaryClass), cls
@@ -29,16 +27,13 @@
 
         item = IntegerParameter(app, "item")
 
-        self.selection = ListParameter(app, "selection", item)
-        self.add_parameter(self.selection)
+        self.ids = ListParameter(app, "id", item)
+        self.add_parameter(self.ids)
 
         self.checkbox_column = ObjectCheckboxColumn \
-            (app, "id", cls._id, self.selection)
+            (app, "id", cls._id, self.ids)
         self.add_column(self.checkbox_column)
 
-        self.links = ObjectSelectorLinks(app, "links")
-        self.add_child(self.links)
-
         self.switches = ObjectSelectorSwitches(app, "switches")
         self.add_child(self.switches)
 
@@ -51,27 +46,29 @@
         # (RosemaryAttribute this, RosemaryAttribute that, Attribute object)
         self.filter_specs = list()
 
+        self.tasks = list()
+
     def init(self):
+        super(ObjectSelector, self).init()
+
         assert self.cls, self
         assert self.adapter, self
         assert self.adapter.id_field, self
 
-        super(ObjectSelector, self).init()
+        for task in self.tasks:
+            task.init()
 
+        for task in self.tasks:
+            button = SelectionTaskButton(self.app, task)
+            self.buttons.add_child(button)
+            button.init()
+
     def add_attribute_column(self, attr):
         assert isinstance(attr, RosemaryAttribute), attr
 
         col = ObjectAttributeColumn(self.app, attr.name, attr)
         self.add_column(col)
 
-    def add_task(self, task, attribute):
-        link = ObjectTaskLink(self.app, task.name, task, attribute)
-        self.links.add_child(link)
-
-    def add_selection_task(self, task):
-        button = SelectionTaskButton(self.app, task.name, task, self.selection)
-        self.buttons.add_child(button)
-
     def add_filter(self, attribute, this, that=None):
         if not that:
             that = this
@@ -177,9 +174,6 @@
         if len(self.children):
             return super(ObjectSelectorControl, self).do_render(session)
 
-class ObjectSelectorLinks(ObjectSelectorControl):
-    pass
-
 class ObjectSelectorSwitches(ObjectSelectorControl):
     pass
 

Modified: mgmt/newdata/cumin/python/cumin/objectselector.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/objectselector.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/objectselector.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -5,11 +5,6 @@
     padding: 0;
 }
 
-div.ObjectSelectorLinks {
-    margin: 0 0 1em 0;
-    font-size: 0.9em;
-}
-
 div.ObjectSelectorFilters {
     float: right;
 }
@@ -24,11 +19,6 @@
     margin: 0 0.5em 0 0;
 }
 
-div.ObjectSelectorButtons ul {
-    padding: 0;
-    margin: 0;
-}
-
 div.ObjectSelectorButtons ul li {
     margin: 0 0.4em 0 0;
     display: inline;
@@ -36,8 +26,6 @@
 
 [ObjectSelector.html]
 <div id="{id}" class="{class}">
-  {links}
-
   {filters}
 
   {switches}

Modified: mgmt/newdata/cumin/python/cumin/objecttask.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/objecttask.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/objecttask.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -12,64 +12,46 @@
 strings = StringCatalog(__file__)
 
 class Task(object):
-    def __init__(self, module, cls, name):
-        assert isinstance(cls, RosemaryClass), cls
+    def __init__(self, app):
+        self.app = app
+        self.name = self.__class__.__name__
 
-        self.app = module.app
-        self.module = module
-        self.cls = cls
-        self.name = name
-
         self.form = None
 
-        assert not hasattr(self.module, self.name), (self.module, self.name)
-
-        self.module.tasks.append(self)
-        setattr(self.module, self.name, self)
-
     def init(self):
         log.info("Initializing %s", self)
 
         assert self.form, self.form
 
-        self.module.app.form_page.modes.add_mode(self.form)
+        # XXX make this idempotent
+        self.app.form_page.modes.add_mode(self.form)
 
-    def get_title(self, session, obj):
+    def get_title(self, session):
         pass
 
-    def get_description(self, session, obj):
-        return self.get_title(session, obj)
+    def get_description(self, session):
+        return self.get_title(session)
 
-    def get_href(self, session, obj):
-        return self.enter(session, obj).marshal()
+    def get_href(self, session):
+        return self.enter(session).marshal()
 
-    def enter(self, session, obj):
-        nsession = wooly.Session(self.module.app.form_page)
-
-        self.form.return_url.set(nsession, session.marshal())
-        self.form.show(nsession)
-
-        self.do_enter(nsession, obj)
-
-        return nsession
-
-    def exit(self, session, obj):
+    def exit(self, session):
         log.debug("Exiting %s", self)
 
         url = self.form.return_url.get(session)
         osession = wooly.Session.unmarshal(self.app, url)
 
-        self.do_exit(osession, obj)
+        self.do_exit(osession)
 
         log.info("Exited %s", self)
 
         return osession
 
-    def do_exit(self, session, obj):
+    def do_exit(self, session):
         pass
 
-    def exit_with_redirect(self, session, obj):
-        osession = self.exit(session, obj)
+    def exit_with_redirect(self, session):
+        osession = self.exit(session)
         self.form.page.redirect.set(session, osession.marshal())
 
     def start(self, session, obj):
@@ -77,23 +59,18 @@
 
         login = session.client_session.attributes["login_session"]
 
-        invoc = TaskInvocation(self, login.user, obj)
+        invoc = TaskInvocation(self, login)
 
         now = datetime.now()
 
         invoc.start_time = now
-        invoc.last_change_time = now
+        invoc.update_time = now
         invoc.status = invoc.PENDING
 
-        self.app.model.task_invocations.append(invoc)
-
         log.info("Started %s", self)
 
         return invoc
 
-    def do_invoke(self, invoc, obj, *args):
-        pass
-
     def qmf_call(self, invoc, obj, meth, *args):
         def completion(status_code, output_args):
             invoc.status_code = status_code
@@ -109,7 +86,7 @@
 
         invoc.status = invoc.FAILED
         invoc.end_time = now
-        invoc.last_change_time = now
+        invoc.update_time = now
         invoc.exception = e
 
         log.exception(e)
@@ -117,39 +94,81 @@
     def __str__(self):
         return "%s.%s" % (self.__module__, self.__class__.__name__)
 
+class ObjectTask(Task):
+    def __init__(self, app, frame):
+        super(ObjectTask, self).__init__(app)
+
+        self.frame = frame
+        self.frame.tasks.append(self)
+
+        self.form = ObjectTaskForm(app, self.name, self)
+
+    def enter(self, session):
+        id = self.frame.id.get(session)
+
+        nsession = wooly.Session(self.app.form_page)
+
+        self.form.id.set(nsession, id)
+        self.form.return_url.set(nsession, session.marshal())
+        self.form.show(nsession)
+
+        self.do_enter(nsession)
+
+        return nsession
+
+    def do_enter(self, session):
+        pass
+
+    def invoke(self, session, obj, *args):
+        if obj:
+            assert isinstance(obj, RosemaryObject), obj
+
+        invoc = self.start(session, obj)
+
+        try:
+            self.do_invoke(invoc, obj, *args)
+        except Exception, e:
+            self.exception(invoc, e)
+
+    def do_invoke(self, invoc, obj, *args):
+        pass
+
 class TaskInvocation(object):
     PENDING = "pending"
     FAILED = "failed"
     OK = "ok"
 
-    def __init__(self, task, user, obj):
+    def __init__(self, task, login_session):
         self.task = task
-        self.user = user
-        self.object = obj
+
+        self.login_session = login_session
+        self.login_session.task_invocations.append(self)
+
         self.start_time = None
         self.end_time = None
-        self.last_change_time = None
+        self.update_time = None
         self.status = None
         self.exception = None
 
         self.status_code = None
         self.output_args = None
 
-        self.results_by_item = dict()
-        self.outstanding_items = set()
+    def get_summary(self, session):
+        if self.exception:
+            return str(self.exception)
 
+        return self.status
+    
     def end(self):
         log.debug("Ending %s", self.task)
 
-        if self.status_code in (None, 0, "OK"):
+        if self.status is self.PENDING:
             self.status = self.OK
-        else:
-            self.status = self.FAILED
 
         now = datetime.now()
 
         self.end_time = now
-        self.last_change_time = now
+        self.update_time = now
 
         log.info("Ended %s", self.task)
 
@@ -163,9 +182,12 @@
     def do_get_items(self, session):
         now = secs(datetime.now())
 
-        invocs = sorted_by(self.app.model.task_invocations, "last_change_time")
-        invocs = [x for x in invocs if now - secs(x.last_change_time) < 10]
+        login = session.client_session.attributes["login_session"]
 
+        invocs = sorted_by(login.task_invocations, "update_time")
+        invocs = [x for x in invocs
+                  if now - secs(x.update_time) < 10 or x.status == x.FAILED]
+
         return invocs
 
     def do_render(self, session):
@@ -175,75 +197,60 @@
             return super(TaskInvocationSet, self).do_render(session)
 
     def render_item_content(self, session, item):
-        description = item.task.get_description(session, item.object)
+        description = item.task.get_description(session)
         description = xml_escape(description)
 
         if not description:
             description = ""
 
-        status = item.status
-        exc = str(item.exception)
-        code = str(item.status_code)
-        outs = str(item.output_args)
+        summary = item.get_summary(session)
 
-        return ": ".join((description, status))
+        return ": ".join((description, summary))
 
-# XXX
-def completion(status_code=0, output_args=()):
-    invoc.results_by_item[item] = (status_code, output_args)
-    invoc.outstanding_items.remove(item)
+class SelectionTask(Task):
+    def __init__(self, app, selector):
+        super(SelectionTask, self).__init__(app)
 
-    if not invoc.outstanding_items:
-        self.end(invoc)
+        self.cls = selector.cls
 
-class ObjectTask(Task):
-    def __init__(self, module, cls):
-        name = self.__class__.__name__
+        self.selector = selector
+        self.selector.tasks.append(self)
 
-        super(ObjectTask, self).__init__(module, cls, name)
+        self.form = SelectionTaskForm(app, self.name, self)
 
-        self.form = ObjectTaskForm(self.app, self.name, self)
+    def get_title(self, session):
+        pass
 
-    def do_enter(self, session, obj):
-        if obj:
-            self.form.id.set(session, obj._id)
+    def enter(self, session):
+        ids = self.selector.ids.get(session)
 
-    def invoke(self, session, obj, *args):
-        if obj:
-            assert isinstance(obj, RosemaryObject), obj
+        nsession = wooly.Session(self.app.form_page)
 
-        invoc = self.start(session, obj)
+        self.form.ids.set(nsession, ids)
+        self.form.return_url.set(nsession, session.marshal())
+        self.form.show(nsession)
 
-        try:
-            self.do_invoke(invoc, obj, *args)
-        except Exception, e:
-            self.exception(invoc, e)
+        self.do_enter(nsession)
 
-class SelectionTask(Task):
-    def __init__(self, item_task):
-        module = item_task.module
-        cls = item_task.cls
-        name = "%s_selection" % item_task.name
+        return nsession
 
-        super(SelectionTask, self).__init__(module, cls, name)
+    def do_enter(self, session):
+        pass
 
-        self.item_task = item_task
-        self.item_task.selection_task = self
-
-        self.form = SelectionTaskForm(self.module.app, self.name, self)
-
-    def do_enter(self, session, ids):
-        if ids:
-            self.form.ids.set(session, ids)
-
     def invoke(self, session, selection, *args):
-        invoc = self.start(session, selection)
-
         for item in selection:
-            invoc.outstanding_items.add(item)
+            invoc = self.start(session, item)
 
-            self.item_task.do_invoke(invoc, item, *args)
+            try:
+                self.do_invoke(invoc, item, *args)
+            except Exception, e:
+                invoc.exception = e
+                invoc.status = invoc.FAILED
+                invoc.end()
 
+    def do_invoke(self, invoc, item, *args):
+        pass
+
 class TaskForm(FoldingFieldSubmitForm):
     def __init__(self, app, name, task):
         assert isinstance(task, Task)
@@ -252,10 +259,12 @@
 
         self.task = task
 
-class ObjectTaskForm(TaskForm):
+class ObjectTaskForm(FoldingFieldSubmitForm):
     def __init__(self, app, name, task):
-        super(ObjectTaskForm, self).__init__(app, name, task)
+        super(ObjectTaskForm, self).__init__(app, name)
 
+        self.task = task
+
         self.id = IntegerParameter(app, "id")
         self.add_parameter(self.id)
 
@@ -265,14 +274,8 @@
         id = self.id.get(session)
 
         if id:
-            conn = self.app.model.get_sql_connection()
-            cursor = conn.cursor()
-
-            try:
-                obj = self.task.cls.get_object(cursor, id)
-            finally:
-                cursor.close()
-
+            # XXX don't love this; impl get_object on OTForm instead
+            obj = self.task.frame.get_object(session, id)
             self.object.set(session, obj)
 
         super(ObjectTaskForm, self).do_process(session)
@@ -281,16 +284,17 @@
         obj = self.object.get(session)
 
         self.task.invoke(session, obj)
-        self.task.exit_with_redirect(session, obj)
+        self.task.exit_with_redirect(session)
 
     def render_title(self, session):
-        obj = self.object.get(session)
-        return self.task.get_title(session, obj)
+        return self.task.get_title(session)
 
 class SelectionTaskForm(TaskForm):
     def __init__(self, app, name, task):
         super(SelectionTaskForm, self).__init__(app, name, task)
 
+        self.cls = task.selector.cls
+
         item = IntegerParameter(app, "item")
 
         self.ids = ListParameter(app, "id", item)
@@ -303,63 +307,41 @@
         
         self.selection.set(session, selection)
 
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
+        for id in self.ids.get(session):
+            item = self.cls.get_object(session.cursor, id)
+            selection.append(item)
 
-        try:
-            for id in self.ids.get(session):
-                item = self.task.cls.get_object(cursor, id)
-                selection.append(item)
-        finally:
-            cursor.close()
-
         super(SelectionTaskForm, self).do_process(session)
     
     def process_submit(self, session):
         selection = self.selection.get(session)
 
         self.task.invoke(session, selection)
-        self.task.exit_with_redirect(session, selection)
+        self.task.exit_with_redirect(session)
 
 class ObjectTaskLink(Link):
-    def __init__(self, app, name, task, attribute=None):
+    def __init__(self, app, name, task):
         assert isinstance(task, ObjectTask), task
 
         super(ObjectTaskLink, self).__init__(app, name)
 
         self.task = task
-        self.attribute = attribute
 
-    def get_object(self, session):
-        if self.attribute:
-            return self.attribute.get(session)
-
     def render_href(self, session):
-        return self.task.get_href(session, self.get_object(session))
+        return self.task.get_href(session)
 
     def render_content(self, session):
-        return self.task.get_title(session, self.get_object(session))
+        return self.task.get_title(session)
 
 class SelectionTaskButton(FormButton):
-    def __init__(self, app, name, task, attribute=None):
-        assert isinstance(task, ObjectTask), task
+    def __init__(self, app, task):
+        super(SelectionTaskButton, self).__init__(app, task.name)
 
-        super(SelectionTaskButton, self).__init__(app, name)
-
         self.task = task
-        self.attribute = attribute
 
-    def get_selection(self, session):
-        if self.attribute:
-            return self.attribute.get(session)
-
     def process_submit(self, session):
-        selection = self.get_selection(session)
-
-        href = self.task.selection_task.get_href(session, selection)
-
+        href = self.task.get_href(session)
         self.page.redirect.set(session, href)
 
     def render_content(self, session):
-        selection = self.get_selection(session)
-        return self.task.get_title(session, selection)
+        return self.task.get_title(session)

Modified: mgmt/newdata/cumin/python/cumin/parameters.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/parameters.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/parameters.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -20,16 +20,6 @@
         obj = self.object.get(session)
         return self.get_associate(session, obj)
 
-class CuminObjectParameter(Parameter):
-    def __init__(self, app, name, cumin_class):
-        self.cumin_class = cumin_class
-
-    def do_unmarshal(self, string):
-        return self.cumin_class.mint_class.get(int(string))
-
-    def do_marshal(self, object):
-        return str(object.id)
-
 class CuminClassParameter(Parameter):
     def do_unmarshal(self, string):
         return getattr(self.app.model, string, None)
@@ -121,23 +111,6 @@
     def do_marshal(self, broker):
         return str(broker.id)
 
-class BrokerVhostAttribute(ObjectAssociateAttribute):
-    def get_associate(self, session, broker):
-        cls = self.app.rosemary.org_apache_qpid_broker.Vhost
-
-        conn = self.app.model.get_sql_connection()
-        cursor = conn.cursor()
-
-        try:
-            kwargs = {"_brokerRef_id": broker._id, "name": "/"}
-
-            for obj in cls.get_selection(cursor, **kwargs):
-                break
-        finally:
-            cursor.close()
-
-        return obj
-
 class ConnectionParameter(Parameter):
     def do_unmarshal(self, string):
         return ClientConnection.get(int(string))

Modified: mgmt/newdata/cumin/python/cumin/sqladapter.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/sqladapter.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/sqladapter.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -18,6 +18,8 @@
             field.init()
 
     def get_count(self, values):
+        # XXX urgh.  I want session in here
+
         conn = self.app.model.get_sql_connection()
         cursor = conn.cursor()
 

Deleted: mgmt/newdata/cumin/python/cumin/table.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/table.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/table.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,109 +0,0 @@
-from wooly import *
-from wooly.datatable import *
-from wooly.forms import *
-from wooly.widgets import *
-
-from util import *
-from widgets import *
-
-strings = StringCatalog(__file__)
-
-# XXX delete this
-
-class SelectionTable(Form):
-    def __init__(self, app, name, data):
-        super(SelectionTable, self).__init__(app, name)
-
-        self.table = self.SelectionDataTable(app, "table", data)
-        self.table.update_enabled = True
-        self.add_child(self.table)
-
-        item = IntegerParameter(app, "item")
-
-        self.selection = ListParameter(app, "selection", item)
-        self.add_parameter(self.selection)
-
-        self.links = SelectionTableLinks(app, "links")
-        self.add_child(self.links)
-
-        self.switches = SelectionTableSwitches(app, "switches")
-        self.add_child(self.switches)
-
-        self.filters = SelectionTableFilters(app, "filters")
-        self.add_child(self.filters)
-
-        self.buttons = SelectionTableButtons(app, "buttons")
-        self.add_child(self.buttons)
-
-        col = self.Checkbox(app, "checkbox", self.table, self.selection)
-        self.table.add_column(col)
-
-        col = self.Name(app, "name", self.table)
-        self.table.add_column(col)
-
-        self.frame_path = None
-
-    def init(self):
-        super(SelectionTable, self).init()
-
-        assert self.frame_path, self
-
-    # XXX this isn't what we do now
-    def do_get_data(self, session, sort, ascending, limit, offset):
-        return self.table.adapter.get_data(sort, ascending, limit, offset)
-
-    def add_task(self, task):
-        link = ObjectTaskLink(self.app, task.__class__.__name__, task)
-        self.links.add_child(link)
-
-    def add_selection_task(self, task):
-        name = task.__class__.__name__
-        button = TaskButton(self.app, name, task, self.selection)
-        self.buttons.add_child(button)
-
-    class Checkbox(NewCheckboxColumn):
-        def render_cell_value(self, session, record):
-            return record[self.table.adapter.id_field.index]
-
-    class Name(LinkColumn):
-        def render_header_content(self, session):
-            return "Name"
-
-        def render_cell_href(self, session, record):
-            branch = session.branch()
-
-            path = self.table.parent.frame_path
-            id = record[self.table.adapter.id_field.index]
-
-            frame = self.page.page_widgets_by_path[path]
-
-            return frame.get_href(session, id)
-
-        def render_cell_content(self, session, record):
-            return record[self.table.adapter.name_field.index]
-
-    class SelectionDataTable(DataTable):
-        def do_get_data(self, session, sort, ascending, limit, offset):
-            return self.parent.do_get_data \
-                (session, sort, ascending, limit, offset)
-
-class SelectionTableControl(WidgetSet):
-    def do_render(self, session):
-        if len(self.children):
-            return super(SelectionTableControl, self).do_render(session)
-
-class SelectionTableLinks(SelectionTableControl):
-    def render_title(self, session):
-        return "Links"
-
-class SelectionTableSwitches(SelectionTableControl):
-    def render_title(self, session):
-        return "Switches"
-
-class SelectionTableFilters(SelectionTableControl):
-    def render_title(self, session):
-        return "Filters"
-
-class SelectionTableButtons(SelectionTableControl):
-    def render_title(self, session):
-        return "Act on selection:"

Deleted: mgmt/newdata/cumin/python/cumin/table.strings
===================================================================
--- mgmt/newdata/cumin/python/cumin/table.strings	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/table.strings	2010-04-14 17:34:58 UTC (rev 3912)
@@ -1,73 +0,0 @@
-[SelectionTable.css]
-div.SelectionTable div.switches ul,
-div.SelectionTable div.filters ul,
-div.SelectionTable div.buttons ul {
-    list-style: none;
-    display: inline;
-    padding: 0;
-    margin: 0;
-}
-
-div.SelectionTable div.filters {
-    float: right;
-}
-
-div.SelectionTable div.buttons ul li {
-    margin: 0 0.4em 0 0;
-    display: inline;
-}
-
-div.SelectionTable form {
-    clear: both;
-}
-
-[SelectionTable.html]
-<div id="{id}" class="{class}">
-  {links}
-
-  {filters}
-
-  {switches}
-
-  <form method="post" action="?">
-    {buttons}
-
-    {table}
-
-    <div>{hidden_inputs}</div>
-  </form>
-</div>
-
-[SelectionTableControl.css]
-div.SelectionTableControl {
-    padding: 0.35em 0.75em;
-}
-
-div.SelectionTableControl ul {
-    list-style: none;
-    display: inline;
-    padding: 0;
-    margin: 0;
-}
-
-[SelectionTableControl.html]
-<div class="{class}">
-  <span>{title}</span>
-
-  <ul>{widgets}</ul>
-</div>
-
-[SelectionTableButtons.css]
-div.SelectionTableButtons {
-    background-color: #e7e7f7;
-}
-
-div.SelectionTableButtons span {
-    font-size: 0.9em;
-    margin: 0 0.5em 0 0;
-}
-
-div.SelectionTableButtons ul li {
-    margin: 0 0.4em 0 0;
-    display: inline;
-}

Modified: mgmt/newdata/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/newdata/cumin/python/cumin/widgets.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/cumin/python/cumin/widgets.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -5,9 +5,9 @@
 from wooly.widgets import *
 from wooly.forms import *
 from wooly.sql import *
+from wooly.tables import *
 from mint.schema import *
 
-from action import *
 from objecttask import *
 from parameters import *
 from widgets import *
@@ -277,7 +277,7 @@
         obj = self.object.get(session)
 
         self.task.invoke(session, obj)
-        self.task.exit_with_redirect(session, obj)
+        self.task.exit_with_redirect(session)
 
     def render_submit_content(self, session):
         return self.task.get_title(session)
@@ -1345,6 +1345,8 @@
 
         self.created = datetime.now()
 
+        self.task_invocations = list()
+
 class CuminPage(HtmlPage):
     def __init__(self, app, name):
         super(CuminPage, self).__init__(app, name)

Modified: mgmt/newdata/misc/boneyard.py
===================================================================
--- mgmt/newdata/misc/boneyard.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/misc/boneyard.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -246,64 +246,3 @@
                 value = p.value
 
     return value
-
-class SessionSet(CuminSelectionTable):
-    def __init__(self, app, name, conn):
-        item = SessionParameter(app, "item")
-        super(SessionSet, self).__init__(app, name, item)
-
-        self.conn = conn
-
-        col = self.NameColumn(app, "name")
-        self.add_column(col)
-        self.set_default_column(col)
-
-        col = self.ExpiresColumn(app, "expires")
-        self.add_column(col)
-
-        col = self.StatusColumn(app, "attached")
-        self.add_column(col)
-
-        self.__phase = PhaseSwitch(app, "phase")
-        self.add_child(self.__phase)
-
-        task = main.module.session_set_detach
-        self.buttons.add_child(TaskButton(app, "detach", task, self.selection))
-
-        task = main.module.session_set_close
-        self.buttons.add_child(TaskButton(app, "close", task, self.selection))
-
-    def render_title(self, session):
-        conn = self.conn.get(session)
-        return "Sessions %s" % fmt_count(conn.sessions.count())
-
-    def render_sql_where(self, session):
-        conn = self.conn.get(session)
-
-        elems = list()
-        elems.append("s.client_connection_id = %(id)r")
-        elems.append(self.__phase.get_sql_constraint(session, conn))
-
-        return "where %s" % " and ".join(elems)
-
-    def get_sql_values(self, session):
-        conn = self.conn.get(session)
-        return {"id": conn.id}
-
-    class NameColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Name"
-
-    class ExpiresColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Expires"
-
-        def render_value(self, session, value):
-            return fmt_datetime(value)
-
-    class StatusColumn(SqlTableColumn):
-        def render_title(self, session):
-            return "Attached?"
-
-        def render_content(self, session, data):
-            return fmt_predicate(data["attached"])

Modified: mgmt/newdata/wooly/python/wooly/datatable.py
===================================================================
--- mgmt/newdata/wooly/python/wooly/datatable.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/wooly/python/wooly/datatable.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -31,8 +31,6 @@
         self.adapter.fields.append(self)
         self.adapter.fields_by_name[self.name] = self
 
-        self.visible = True
-
     def init(self):
         pass
 

Modified: mgmt/newdata/wooly/python/wooly/table.py
===================================================================
--- mgmt/newdata/wooly/python/wooly/table.py	2010-04-14 14:53:31 UTC (rev 3911)
+++ mgmt/newdata/wooly/python/wooly/table.py	2010-04-14 17:34:58 UTC (rev 3912)
@@ -201,7 +201,7 @@
     def __init__(self, app, name):
         super(NewCheckboxColumn, self).__init__(app, name)
 
-        self.selection = selection
+        self.selection = selection # XXX huh?
 
         self.header = CheckboxColumnHeader(app, "header")
         self.replace_child(self.header)
@@ -234,11 +234,5 @@
         return self.input.render(session, record)
 
 class CheckboxColumnInput(CheckboxInput):
-    def render_onclick_attr(self, session, record):
-        value = "wooly.clickTableCheckbox(this, '%s')" % \
-            self.parent.parent.selection.path
-
-        return "onclick=\"%s\"" % value
-
     def render_value(self, session, record):
         return self.parent.parent.render_cell_value(session, record)



More information about the rhmessaging-commits mailing list