Author: eallen
Date: 2011-02-08 23:28:56 +0000 (Tue, 08 Feb 2011)
New Revision: 4509
Modified:
trunk/cumin/python/cumin/grid/job.py
trunk/cumin/python/cumin/grid/limit.py
trunk/cumin/python/cumin/grid/negotiator.py
trunk/cumin/python/cumin/grid/pool.py
trunk/cumin/python/cumin/grid/quota.py
trunk/cumin/python/cumin/grid/quota.strings
trunk/cumin/python/cumin/grid/submission.py
trunk/cumin/python/cumin/messaging/binding.py
trunk/cumin/python/cumin/model.py
trunk/cumin/python/cumin/objectselector.py
trunk/cumin/python/cumin/objectselector.strings
trunk/cumin/python/cumin/qmfadapter.py
trunk/cumin/python/cumin/widgets.py
Log:
Consolidated Job Summaries, Quotas, and Limits to use the same base classes for qmf
exception handling, csv exporting, results sorting and paging.
Modified: trunk/cumin/python/cumin/grid/job.py
===================================================================
--- trunk/cumin/python/cumin/grid/job.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/job.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,22 +1,24 @@
import logging
+from datetime import datetime
-from wooly import *
-from wooly.widgets import *
-from wooly.forms import *
-from wooly.resources import *
-from wooly.tables import *
-from time import time
-from cumin.widgets import *
-from cumin.model import FetchJobAd, FetchJobOutput
-from cumin.objecttask import *
-from cumin.parameters import *
-from cumin.stat import *
-from cumin.formats import *
-from cumin.util import *
-from cumin.qmfadapter import *
-from parsley.stringex import partition
+from cumin.objectframe import ObjectView, ObjectFrameTaskForm, ObjectFrame,\
+ ObjectFrameTask
+from cumin.qmfadapter import ObjectQmfAdapter
+from cumin.objectselector import ObjectTableColumn, ObjectLinkColumn,\
+ ObjectQmSelectorfTable, ObjectCheckboxColumn,\
+ ObjectSelectorTask, ObjectSelectorTaskForm, ObjectQmfSelector
+from cumin.widgets import StaticColumnHeader, Wait, CuminForm,\
+ EditablePropertyRenderer, StateSwitch
+from cumin.util import JobStatusInfo, strip_string_quotes, parse
+from cumin.model import QmfCall
+from cumin.formats import fmt_datetime, fmt_link
-import main
+from wooly import Widget, Parameter, Attribute
+from wooly.util import StringCatalog, Writer, escape_amp, escape_entity
+from wooly.forms import Form, FormButton, StringField
+from wooly.widgets import ModeSet, PropertySet, TemplateRenderer
+from wooly.template import WidgetTemplate
+from wooly.parameters import ListParameter, IntegerParameter, DictParameter
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.job")
@@ -101,35 +103,26 @@
return self.frame.get_title(session)
class JobSummariesAdapter(ObjectQmfAdapter):
- def get_qmf_response(self, values):
- try:
- submission = values["obj"]
- except:
- return None
+ def __init__(self, app, cls, submission):
+ super(JobSummariesAdapter, self).__init__(app, cls)
+ self.submission = submission
+
+ def get_qmf_results(self, values):
+ session = values['session']
+ submission = self.submission.get(session)
+
return self.app.model.get_submission_job_summaries(submission)
- def get_data(self, values, options):
- results = self.get_qmf_response(values)
+ def do_get_data(self, values):
+ results = self.get_qmf_results(values)
+ summaries = results.data
- if not results:
+ if summaries is None or len(summaries) == 0:
return []
- rows = self.process_list_results(results.data)
+ return summaries
- # sort the entire results set
- rows = self.sort_rows(rows, options)
-
- # return only the current page
- first_index = options.offset
- last_index = len(rows)
- if options.limit:
- last_index = options.offset + options.limit
-
- page = rows[first_index:last_index]
-
- return page
-
def process_record(self, key, record):
field_data = list()
for column in self.columns:
@@ -147,7 +140,7 @@
parts = gjid.split("#")
if len(parts) == 3:
val = parts[1]
- except Exception, e:
+ except Exception:
pass
if not val:
try:
@@ -160,9 +153,8 @@
return field_data
def get_count(self, values):
- submission = values["obj"]
- results = self.app.model.get_submission_job_summaries(submission)
- return results.data and len(results.data) or 0
+ data = self.do_get_data(values)
+ return len(data)
class NonSortableObjectTableColumn(ObjectTableColumn):
def __init__(self, app, name, attr):
@@ -207,14 +199,13 @@
self.header = DynamicColumnHeader(app, "dynamic_header",
selector_method, self)
self.add_child(self.header)
-class JobSelector(ObjectSelector):
+class JobSelector(ObjectQmfSelector):
def __init__(self, app, name, submission):
cls = app.model.com_redhat_cumin_grid.JobSummary
- self.defer_enabled = True
super(JobSelector, self).__init__(app, name, cls)
- self.table.adapter = JobSummariesAdapter(app, cls)
+ self.table.adapter = JobSummariesAdapter(app, cls, submission)
self.submission = submission
frame = "main.grid.pool.submission.job"
@@ -242,6 +233,10 @@
def create_table(self, app, name, cls):
return JobSelectorTable(app, name, cls)
+ def get_qmf_results(self, session):
+ values = self.get_data_values(session)
+ return self.table.adapter.get_qmf_results(values)
+
def render_dynamic_header(self, session):
values = self.get_data_values(session)
count = self.table.adapter.get_count(values)
@@ -249,12 +244,6 @@
return count <= max_sort
- def do_render(self, session):
- if self.table.is_exception(session):
- return self.table.render(session)
-
- return super(JobSelector, self).do_render(session)
-
def render_title(self, session):
return "Jobs"
@@ -269,12 +258,7 @@
submission = self.parent.parent.submission.get(session)
return frame.get_href(session, submission._id, job_id)
-class JobSelectorTable(ObjectSelectorTable):
- def __init__(self, app, name, cls):
- super(JobSelectorTable, self).__init__(app, name, cls)
-
- self.error_tmpl = WidgetTemplate(self, "error_html")
-
+class JobSelectorTable(ObjectQmSelectorfTable):
def init_ids(self, app, cls):
item = Parameter(app, "item")
@@ -285,52 +269,6 @@
(app, "id", cls.JobId, self.ids)
self.add_column(self.checkbox_column)
- def get_data_values(self, session):
- values = super(JobSelectorTable, self).get_data_values(session)
-
- submission = self.parent.submission.get(session)
-
- if submission:
- values['obj'] = submission
- values['args'] = ()
- return values
-
- def get_data(self, session):
- values = self.get_data_values(session)
- options = self.get_data_options(session)
-
- return self.adapter.get_data(values, options)
-
- def is_exception(self, session):
- values = self.get_data_values(session)
- qmf_response = self.adapter.get_qmf_response(values)
-
- if not qmf_response:
- return True
-
- return qmf_response.exception and True or False
-
- def do_render(self, session):
- # determine if there is an error getting the data
- # and show an error message
- values = self.get_data_values(session)
- qmf_response = self.adapter.get_qmf_response(values)
- if not qmf_response:
- m = ""
- elif qmf_response.exception:
- e = qmf_response.exception
- m = len(e.args) > 0 and e.args[0] or ""
- if (not qmf_response) or qmf_response.exception:
- writer = Writer()
- msg = "The data is not available at this time. <br/>%s" % m
- self.error_tmpl.render(writer, session, msg)
- return writer.to_string()
-
- return super(JobSelectorTable, self).do_render(session)
-
- def render_error_msg(self, session, msg):
- return msg
-
class JobObjectSelectorTask(ObjectSelectorTask):
def __init__(self, app, selector, verb):
super(JobObjectSelectorTask, self).__init__(app, selector)
@@ -800,8 +738,6 @@
user_file = None
err_file = None
- id = self.frame.id.get(session)
- scheduler = self.frame.get_scheduler(session, id)
ads, error = self.do_get_items(session)
for ad in ads:
if ad['name'] == "Out":
Modified: trunk/cumin/python/cumin/grid/limit.py
===================================================================
--- trunk/cumin/python/cumin/grid/limit.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/limit.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,31 +1,31 @@
import logging
-from wooly import *
-from wooly.widgets import *
-from wooly.forms import *
-from wooly.resources import *
-from wooly.tables import *
-from cumin.stat import *
-from cumin.widgets import *
-from cumin.parameters import *
-from cumin.formats import *
-from cumin.util import *
+from cumin.formats import fmt_link
+from cumin.model import QmfCall
+from cumin.objectselector import ObjectTableColumn, ObjectQmfSelector,\
+ ObjectQmfTable
+from cumin.objectframe import ObjectFrame, ObjectFrameTask, ObjectFrameTaskForm
+from cumin.qmfadapter import ObjectQmfAdapter
+from cumin.widgets import CuminView
-from job import *
+from wooly.forms import StringField, StringInput, IntegerField
+from wooly.util import StringCatalog
+from wooly.widgets import TabbedModeSet
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.limit")
-class LimitDataSet(object):
- def __init__(self, app, collector):
- self.app = app
+class LimitAdapter(ObjectQmfAdapter):
+ def __init__(self, app, cls, collector):
+ super(LimitAdapter, self).__init__(app, cls)
+
self.collector = collector
def get_negotiator(self, session):
collector = self.collector.get(session)
cls = self.app.model.com_redhat_grid.Negotiator
- # TODO: why is there more than 1 negotiator?
+ # mis-configured pool if there is more than one negotiator
negs = cls.get_selection(session.cursor, Pool=collector.Pool)
try:
youngest = negs[0]
@@ -39,88 +39,96 @@
return negotiator
- def get_items(self, session):
+ def get_count(self, values):
+ data = self.do_get_data(values)
+ return len(data)
+
+ def get_qmf_results(self, values):
+ # used to get the cached limits, and to determine
+ # if there was an exception while getting the data
+
+ session = values['session']
negotiator = self.get_negotiator(session)
- if not negotiator:
- return
+ return self.app.model.get_negotiator_limits(negotiator)
- limits = self.app.model.get_negotiator_limits(negotiator)
+ def do_get_data(self, values):
+ results = self.get_qmf_results(values)
+ limits = results.data
if limits is None or len(limits) == 0:
- return ()
- #limits = {'a':{'CURRENT': 1, 'MAX': 2}}
+ return {}
+ #limits = {'a':{'CURRENT': 11, 'MAX': 22},
+ # 'b':{'CURRENT': 3, 'MAX': 44}}
- keys = limits.keys()
- keys.sort()
+ return limits
- return [{"name": x,
- "curr": limits[x]["CURRENT"],
- "max": limits[x]["MAX"]}
- for x in keys]
+ def process_record(self, key, record):
+ return [key, record["CURRENT"], record["MAX"]]
-class LimitSet(CuminItemTable):
- def __init__(self, app, name, collector):
- super(LimitSet, self).__init__(app, name)
+class LimitTable(ObjectQmfTable):
+ def __init__(self, app, name, cls):
+ super(LimitTable, self).__init__(app, name, cls)
- self.data = LimitDataSet(app, collector)
-
- self.defer_enabled = True
-
- col = self.NameColumn(app, "name")
+ col = self.NameColumn(app, "name", cls.Name)
self.add_column(col)
- self.set_default_column(col)
- col = self.CurrentColumn(app, "curr")
- col.align = "right"
+ col = self.UsageColumn(app, "curr", cls.Usage)
self.add_column(col)
- col = self.MaxColumn(app, "max")
- col.align = "right"
+ col = self.MaxColumn(app, "max", cls.Allowance)
self.add_column(col)
- def do_get_items(self, session):
- return self.data.get_items(session)
+ class NameColumn(ObjectTableColumn):
+ def render_cell_content(self, session, data):
+ limit_name = super(LimitTable.NameColumn, self).render_cell_content(session,
data)
+ if session.page == self.app.export_page:
+ return limit_name
- def render_title(self, session):
- return "Limits"
-
- class NameColumn(NonSortableTableColumn):
- def render_title(self, session):
- return "Name"
-
- def render_content(self, session, data):
- limit_name = data["name"]
- try:
- limit_max = int(data["max"])
- except:
- limit_max = "0"
- negotiator = self.parent.data.get_negotiator(session)
+ limit_max = data[2]
+ negotiator = self.parent.adapter.get_negotiator(session)
self.frame.limit.id.set(session, negotiator._id)
self.frame.limit.set_limit.form.limit_name.set(session, limit_name)
self.frame.limit.set_limit.form.limit_max.set(session, limit_max)
href = self.frame.limit.set_limit.get_href(session)
return fmt_link(href, limit_name)
- class CurrentColumn(NonSortableTableColumn):
- def render_title(self, session):
- return "Current Usage"
+ class UsageColumn(ObjectTableColumn):
+ def render_text_align(self, session):
+ return "right"
- class MaxColumn(NonSortableTableColumn):
- def render_title(self, session):
- return "Max Allowance"
+ class MaxColumn(ObjectTableColumn):
+ def render_text_align(self, session):
+ return "right"
- def render_content(self, session, data):
+ def render_cell_content(self, session, data):
+ limit_max = super(LimitTable.MaxColumn, self).render_cell_content(session,
data)
try:
- limit_max = int(data["max"])
+ limit_max = int(limit_max)
except:
- limit_max = "0"
+ limit_max = 0
return limit_max
- class Limits(Attribute):
- def get_default(self, session):
- return dict()
+class LimitSelector(ObjectQmfSelector):
+ def __init__(self, app, name, collector):
+ cls = app.model.com_redhat_cumin_grid.Limit
+ super(LimitSelector, self).__init__(app, name, cls)
+
+ self.table.adapter = LimitAdapter(app, cls, collector)
+
+ self.enable_csv_export(collector)
+
+ def create_table(self, app, name, cls):
+ return LimitTable(app, name, cls)
+
+ def render_title(self, session):
+ return "Limits"
+
+ def get_qmf_results(self, session):
+ values = self.get_data_values(session)
+ return self.table.adapter.get_qmf_results(values)
+
class LimitFrame(ObjectFrame):
def __init__(self, app, name):
cls = app.model.com_redhat_grid.Negotiator
Modified: trunk/cumin/python/cumin/grid/negotiator.py
===================================================================
--- trunk/cumin/python/cumin/grid/negotiator.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/negotiator.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -69,11 +69,10 @@
self.add_attribute(self.results)
def get_config_info(self, session):
- negotiator = self.negotiator.get(session)
-
info = self.info.get(session)
if not info:
+ negotiator = self.negotiator.get(session)
info = self.get_group_info(session, negotiator)
self.info.set(session, info)
@@ -84,13 +83,7 @@
groups = results.data
info = dict()
- if not groups:
- if (not results.status) and (not results.exception):
- results.exception = Exception("Loading")
-
if not results.exception:
- if not groups:
- results.exception = Exception(results.status)
try:
groups = self.split_group_names(groups)
except Exception, e:
@@ -106,11 +99,9 @@
return info
def get_results(self, session):
- self.get_config_info(session)
- return self.results.get(session)
+ return self.get_config_info(session)
def has_child(self, session, group):
- negotiator = self.negotiator.get(session)
info = self.get_config_info(session)
try:
@@ -126,7 +117,6 @@
return info[group]['has_child']
def get_parent(self, session, group):
- negotiator = self.negotiator.get(session)
info = self.get_config_info(session)
try:
@@ -144,7 +134,6 @@
return info[group]['parent']
def get_siblings(self, session, node):
- negotiator = self.negotiator.get(session)
info = self.get_config_info(session)
siblings = list()
Modified: trunk/cumin/python/cumin/grid/pool.py
===================================================================
--- trunk/cumin/python/cumin/grid/pool.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/pool.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,35 +1,23 @@
import logging
-from wooly import *
-from wooly.forms import *
-from wooly.resources import *
-from wooly.sql import *
-from wooly.tables import *
-from wooly.widgets import *
+from cumin.widgets import Session, StateSwitch
+from wooly.util import StringCatalog
+from cumin.objectselector import ObjectSelector, ObjectLinkColumn
+from rosemary.sqlfilter import SqlComparisonFilter
+from cumin.objectframe import ObjectFrame
+from submission import SubmissionFrame, PoolSubmissionJoinSelector
+from slot import SlotFrame, SlotSelector, SlotMap, SlotMapPage
+from scheduler import SchedulerFrame, SchedulerSelector
+from negotiator import NegotiatorFrame, NegotiatorSelector,\
+ NegotiatorEditDynamicQuota
+from limit import LimitFrame, LimitSelector
+from quota import QuotaSelector
+from wooly import Attribute, Widget
+from cumin.parameters import CollectorGridAttribute, RosemaryObjectParameter
+from collector import CollectorGeneralStatSet
+from cumin.stat import StatFlashChart, StatSet, FlashFullPage
-from cumin.objectframe import *
-from cumin.objectselector import *
-from cumin.stat import *
-from cumin.widgets import *
-from cumin.parameters import *
-from cumin.formats import *
-from cumin.util import *
-from collector import *
-from job import *
-from limit import *
-from negotiator import *
-from quota import *
-from scheduler import *
-from slot import *
-from submission import *
-from submitter import *
-
-from cumin.widgets import Session
-
-import cumin.model
-import main
-
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.pool")
@@ -105,7 +93,7 @@
self.quotas = QuotaSelector(app, "quotas", self.negotiator_attribute,
self)
self.view.add_tab(self.quotas)
- self.limits = LimitSet(app, "limits", self.object)
+ self.limits = LimitSelector(app, "limits", self.object)
self.view.add_tab(self.limits)
class NegotiatorAttribute(Attribute):
Modified: trunk/cumin/python/cumin/grid/quota.py
===================================================================
--- trunk/cumin/python/cumin/grid/quota.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/quota.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,11 +1,15 @@
-from wooly.util import StringCatalog, Writer
import logging
-from cumin.widgets import StaticColumnHeader
+
+from negotiator import GroupHelper
+
from cumin.formats import fmt_link
-from cumin.objectselector import ObjectTable, ObjectSelector, ObjectTableColumn
-from wooly.template import WidgetTemplate
+from cumin.objectselector import ObjectQmfSelector, ObjectTableColumn,\
+ ObjectQmfTable
from cumin.qmfadapter import ObjectQmfAdapter
-from negotiator import GroupHelper
+from cumin.widgets import StaticColumnHeader
+
+from wooly.template import WidgetTemplate
+from wooly.util import StringCatalog, Writer
from wooly import Parameter, Widget
strings = StringCatalog(__file__)
@@ -53,12 +57,10 @@
def get_count(self, values):
return len(values['items'])
-class QuotaTable(ObjectTable):
+class QuotaTable(ObjectQmfTable):
def __init__(self, app, name, cls):
super(QuotaTable, self).__init__(app, name, cls)
- self.update_enabled = False
-
limit = Widget(app, "limit")
self.header.replace_child(limit)
@@ -111,13 +113,14 @@
return values
-class QuotaSelector(ObjectSelector):
+class QuotaSelector(ObjectQmfSelector):
def __init__(self, app, name, negotiator, frame):
cls = app.model.com_redhat_cumin_grid.Quota
super(QuotaSelector, self).__init__(app, name, cls)
self.update_enabled = True
+ self.table.update_enabled = False
self.negotiator = negotiator
self.table.negotiator = negotiator
@@ -144,51 +147,16 @@
self.enable_csv_export(negotiator)
- self.error_tmpl = WidgetTemplate(self, "error_html")
- self.loading_tmpl = WidgetTemplate(self, "deferred_html")
-
def create_table(self, app, name, cls):
return QuotaTable(app, name, cls)
def render_title(self, session):
return "Quotas"
- def do_render(self, session):
- # determine if there is an error getting the data
- # and show an error message
- qmf_response = None
- tmpl = self.error_tmpl
- m = ""
+ def get_qmf_results(self, session):
+ negotiator = self.negotiator.get(session)
+ return self.app.model.get_negotiator_group_names(negotiator)
- try:
- qmf_response = self.group_helper.get_results(session)
- if not qmf_response:
- m = ""
- elif qmf_response.exception:
- e = qmf_response.exception
- m = len(e.args) > 0 and e.args[0] or ""
- if m == "Loading":
- tmpl = self.loading_tmpl
- else:
- neg = self.negotiator.get(session)
- neg_name = neg and " for negotiator %s" % neg.Name or
""
- m = "%s%s" % (m, neg_name)
- except AssertionError:
- m = "Missing Negotiator"
-
- if (not qmf_response) or qmf_response.exception:
- writer = Writer()
- if "is unknown" in m:
- m = "Please try again later"
- err_msg = "The data is not available at this time. <br/>%s" %
m
- tmpl.render(writer, session, err_msg)
- return writer.to_string()
-
- return super(QuotaSelector, self).do_render(session)
-
- def render_error_msg(self, session, msg):
- return msg
-
class ExpandColumn(ObjectTableColumn):
def __init__(self, app, name, attr, expand, group_helper):
super(QuotaSelector.ExpandColumn, self).__init__(app, name, attr)
Modified: trunk/cumin/python/cumin/grid/quota.strings
===================================================================
--- trunk/cumin/python/cumin/grid/quota.strings 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/quota.strings 2011-02-08 23:28:56 UTC (rev 4509)
@@ -5,25 +5,3 @@
color: red;
}
-[QuotaSelector.deferred_html]
-<div id="{id}">
- <div class="deferredSpacer">Loading...</div>
-</div>
-<script type="text/javascript">
-<![CDATA[
-(function() {
- window.addEvent("domready", function () {
- setTimeout( function () { window.location.reload(); }, 5000 );
- });
-}())
-]]>
-</script>
-
-[QuotaSelector.error_html]
-<div id="{id}">
- <div class="TaskInvocationSet">
- <ul>
- <li>{error_msg}</li>
- </ul>
- </div>
-</div>
Modified: trunk/cumin/python/cumin/grid/submission.py
===================================================================
--- trunk/cumin/python/cumin/grid/submission.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/grid/submission.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,18 +1,23 @@
import logging
import shlex
-
from random import choice
+import os
-from rosemary.sqlquery import *
-from parsley.stringex import partition, rpartition
+from job import JobSelector, JobFrame
+from cumin.objectframe import ObjectFrame
+from cumin.sqladapter import ObjectSqlAdapter
+from cumin.objectselector import ObjectSelector, ObjectLinkColumn,\
+ ObjectTableColumn
+from cumin.task import TaskLink, Task, ObjectTaskForm
+from cumin.parameters import ObjectAttribute
-from cumin.objectframe import *
-from cumin.objectselector import *
-from cumin.objecttask import *
-from cumin.widgets import *
-from cumin.util import *
+from rosemary.sqlfilter import SqlFilter
+from rosemary.sqlquery import SqlInnerJoin
-from job import JobSelector, JobFrame
+from wooly import Attribute, Parameter
+from wooly.forms import StringField, ScalarField, FormError, OptionInputSet,\
+ MultilineStringField, FormField, IntegerField
+from wooly.parameters import IntegerParameter
log = logging.getLogger("cumin.grid.submission")
Modified: trunk/cumin/python/cumin/messaging/binding.py
===================================================================
--- trunk/cumin/python/cumin/messaging/binding.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/messaging/binding.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -10,6 +10,7 @@
from cumin.widgets import *
import main
+from cumin.objectframe import ObjectFrameTaskForm
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.messaging.exchange")
Modified: trunk/cumin/python/cumin/model.py
===================================================================
--- trunk/cumin/python/cumin/model.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/model.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -73,7 +73,10 @@
return session
def get_negotiator_group_names(self, negotiator):
- assert negotiator
+ if not negotiator:
+ store = NegotiatorGroupNamesStore(self, None)
+ store.exception = Exception("Missing Negotiator")
+ return store
self.lock.acquire()
@@ -132,7 +135,10 @@
self.lock.release()
def get_negotiator_limits(self, negotiator):
- assert negotiator
+ if not negotiator:
+ store = NegotiatorLimitStore(self, None)
+ store.exception = Exception("Missing Negotiator")
+ return store
self.lock.acquire()
@@ -146,9 +152,7 @@
self.limits_by_negotiator[negotiator._qmf_agent_id] = store
- sleep(1)
-
- return store.data
+ return store
finally:
self.lock.release()
Modified: trunk/cumin/python/cumin/objectselector.py
===================================================================
--- trunk/cumin/python/cumin/objectselector.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/objectselector.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,14 +1,24 @@
-from objectframe import *
-from objecttask import *
-from qmfadapter import *
-from sqladapter import *
-from util import *
-from wooly import *
-from wooly.datatable import *
-from wooly.forms import *
-from wooly.widgets import *
+from cumin.objectframe import ObjectFrame
+from cumin.qmfadapter import ObjectQmfAdapter, ObjectQmfField
+from cumin.sqladapter import ObjectSqlAdapter, ObjectSqlField
+from cumin.util import Identifiable
+from rosemary.model import RosemaryClass, RosemaryAttribute, RosemaryReference
+from rosemary.sqlfilter import SqlLikeFilter
+from wooly.util import StringCatalog, Writer, escape_entity
+from wooly.datatable import DataTable, DataTableColumn
+from wooly import Attribute, Widget, SessionAttribute, Parameter
+from wooly.forms import Form, StringInput, FoldingFieldSubmitForm
+from cumin.objecttask import ObjectTaskButton, ObjectTask
+from wooly.parameters import IntegerParameter, ListParameter
+from wooly.table import CheckboxColumnCell, CheckboxColumnHeader,\
+ CheckboxColumnInput, LinkColumn
+from wooly.widgets import WidgetSet, ItemSet
+import wooly
+from wooly.template import WidgetTemplate
+
+
strings = StringCatalog(__file__)
class ObjectTable(DataTable):
@@ -486,3 +496,110 @@
page.modes.show_child(export_session, self.exporter)
page.set_parameters(export_session, session, self.object_attributes,
self.file_name)
return escape_entity(export_session.marshal())
+
+class QmfDetails(Widget):
+ def __init__(self, app, name, status):
+ super(QmfDetails, self).__init__(app, name)
+
+ self.status = status
+
+ def do_render(self, session):
+ if self.status.get(session):
+ return super(QmfDetails, self).do_render(session)
+ return ""
+
+ def render_details(self, session):
+ status = self.status.get(session)
+ return status
+
+ def render_details_path(self, session):
+ return self.parent.show_details.path
+
+ def render_style(self, session):
+ show = self.parent.show_details.get(session)
+ return show and "block" or "none"
+
+ def render_show(self, session):
+ show = self.parent.show_details.get(session)
+ return show and "hide" or "show"
+
+class ObjectQmfSelector(ObjectSelector):
+ def __init__(self, app, name, cls):
+ super(ObjectQmfSelector, self).__init__(app, name, cls)
+
+ self.update_enabled = True
+ self.table.update_enabled = False
+
+ self.show_details = Parameter(app, "sd")
+ self.add_parameter(self.show_details)
+
+ self.status_msg = Attribute(app, "status")
+ self.add_attribute(self.status_msg)
+
+ self.details = QmfDetails(app, "details", self.status_msg)
+ self.add_child(self.details)
+
+ self.error_tmpl = WidgetTemplate(self, "error_html")
+ self.loading_tmpl = WidgetTemplate(self, "deferred_html")
+
+ def init(self):
+ super(ObjectQmfSelector, self).init()
+
+ assert self.get_qmf_results
+
+ def do_render(self, session):
+ tmpl = self.error_tmpl
+ title = self.render_title(session)
+
+ store = self.get_qmf_results(session)
+ self.status_msg.set(session, store.status)
+ error = None
+
+ if store.exception:
+ error = store.exception
+ if "is unknown" in str(error):
+ error = "%s are not available at this time." % title
+ self.status_msg.set(session, store.exception)
+ else:
+ if store.status is None:
+ error = "Loading"
+ tmpl = self.loading_tmpl
+ else:
+ values = self.table.get_data_values(session)
+ count = self.table.adapter.get_count(values)
+ if count == 0:
+ error = "There are no %s" % title
+
+ if store.status == "OK":
+ details = "The call to get the data suceeded, but no results
were returned."
+ else:
+ details = "The call status is
<span>%s</span>" % store.status
+ self.status_msg.set(session, details)
+
+ if error:
+ writer = Writer()
+ tmpl.render(writer, session, "%s" % error)
+ return writer.to_string()
+
+ return super(ObjectQmfSelector, self).do_render(session)
+
+ def render_error_msg(self, session, msg):
+ return msg
+
+class ObjectQmfTable(ObjectTable):
+ def get_data_values(self, session):
+ values = super(ObjectQmfTable, self).get_data_values(session)
+
+ # session is needed to retrieve the qmf data
+ values['session'] = session
+
+ return values
+
+class ObjectQmSelectorfTable(ObjectSelectorTable):
+ def get_data_values(self, session):
+ values = super(ObjectQmSelectorfTable, self).get_data_values(session)
+
+ # session is needed to retrieve the qmf data
+ values['session'] = session
+
+ return values
Modified: trunk/cumin/python/cumin/objectselector.strings
===================================================================
--- trunk/cumin/python/cumin/objectselector.strings 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/objectselector.strings 2011-02-08 23:28:56 UTC (rev 4509)
@@ -87,3 +87,79 @@
[ExportButton.html]
<a href="{href}"><img src="resource?name=csv.png"
alt="save as csv" title="Save table as CSV file" /></a>
+
+[ObjectQmfSelector.css]
+div.TaskInvocationSet ul {
+ list-style-type: none;
+}
+
+[ObjectQmfSelector.deferred_html]
+<div id="{id}">
+ <div class="deferredSpacer">Loading...</div>
+</div>
+<script type="text/javascript">
+<![CDATA[
+(function() {
+
+ if (typeof window.reUpdated == "undefined") {
+ window.reUpdated = true;
+ window.addEvent("domready", function () {
+ setInterval( function () {
+ wooly.updateNow();
+ }, 5000 );
+ });
+ }
+
+}())
+]]>
+</script>
+
+[ObjectQmfSelector.error_html]
+<div id="{id}">
+ <div class="TaskInvocationSet">
+ <ul>
+ <li>{error_msg} {details}</li>
+ </ul>
+ </div>
+</div>
+
+[QmfDetails.css]
+div.QmfDetails {
+ margin: 1em;
+}
+div.QmfDetails span.DetailsLink {
+ font-size: 80%;
+}
+
+div.QmfDetails div.Details span {
+ font-style: italic;
+ font-weight: bold;
+}
+
+[QmfDetails.html]
+<div id="{id}" class="{class}">
+ <span class="DetailsLink"><a onclick="showDetails(); return
false;">[<span id="{id}_link">{show}</span>
details]</a></span>
+ <div id="{id}_details" class="Details" style="display:
{style};">{details}</div>
+</div>
+<script type="text/javascript">
+<![CDATA[
+ function showDetails() {
+ var updateUrl = wooly.branchIntervalUpdate();
+ var branch = updateUrl["session"];
+
+ var details = $("{id}_details");
+ var show_hide = $("{id}_link");
+ if (details.style.display == "block") {
+ show_hide.innerHTML = "show";
+ details.style.display = "none";
+ delete branch["{details_path}"];
+ } else {
+ show_hide.innerHTML = "hide";
+ details.style.display = "block";
+ branch["{details_path}"] = "1";
+ }
+ //updateUrl["session"] = branch;
+ wooly.restartIntervalUpdate(updateUrl.marshal());
+ }
+]]>
+</script>
Modified: trunk/cumin/python/cumin/qmfadapter.py
===================================================================
--- trunk/cumin/python/cumin/qmfadapter.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/qmfadapter.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -1,8 +1,6 @@
-from rosemary.sqlquery import *
-from wooly.datatable import *
-
-from util import *
from operator import itemgetter
+from cumin.model import QmfCall
+from wooly.datatable import DataAdapter, DataAdapterField
class QmfAdapter(DataAdapter):
def __init__(self, app, method):
@@ -24,6 +22,21 @@
return results and len(results) or 0
def get_data(self, values, options):
+ data = self.do_get_data(values)
+
+ if isinstance(data, dict):
+ rows = self.process_results(data)
+ elif isinstance(data, list):
+ rows = self.process_list_results(data)
+ else:
+ rows = []
+
+ rows = self.sort_rows(rows, options)
+ rows = self.limit_rows(rows, options)
+
+ return rows
+
+ def do_get_data(self, values):
obj = values['obj']
args = values['args']
@@ -33,17 +46,8 @@
if results.error:
results.data = self.default
- if isinstance(results.data, dict):
- rows = self.process_results(results.data)
- elif isinstance(results.data, list):
- rows = self.process_list_results(results.data)
- else:
- rows = []
+ return results.data
- rows = self.sort_rows(rows, options)
-
- return rows[options.offset:options.offset + options.limit]
-
def process_results(self, results):
""" take the dict response from the qmf call and return a list of
lists """
@@ -86,6 +90,17 @@
return sorted(rows, key=itemgetter(sort_field.index), reverse=rev)
+ def limit_rows(self, rows, options):
+ # return only the current page
+ first_index = options.offset
+ last_index = len(rows)
+ if options.limit:
+ last_index = options.offset + options.limit
+
+ page = rows[first_index:last_index]
+
+ return page
+
class ObjectQmfAdapter(QmfAdapter):
def __init__(self, app, cls):
super(ObjectQmfAdapter, self).__init__(app, cls._name)
Modified: trunk/cumin/python/cumin/widgets.py
===================================================================
--- trunk/cumin/python/cumin/widgets.py 2011-02-08 14:59:27 UTC (rev 4508)
+++ trunk/cumin/python/cumin/widgets.py 2011-02-08 23:28:56 UTC (rev 4509)
@@ -21,6 +21,7 @@
from wooly import Session
from wooly.widgets import Link
from wooly.tables import SqlTable
+from cumin.objectframe import ObjectFrameTask
strings = StringCatalog(__file__)
@@ -949,7 +950,8 @@
self.add_parameter(self.param)
def do_get_items(self, session):
- return list(BrokerGroup.select()) #XXX avoid list()ing this?
+ return []
+ #return list(BrokerGroup.select()) #XXX avoid list()ing this?
def render_item_value(self, session, group):
return group.id