Author: eallen
Date: 2008-09-05 13:13:53 -0400 (Fri, 05 Sep 2008)
New Revision: 2421
Modified:
mgmt/trunk/cumin/python/cumin/job.py
mgmt/trunk/cumin/python/cumin/job.strings
mgmt/trunk/cumin/python/cumin/model.py
Log:
First cut a property groups
Modified: mgmt/trunk/cumin/python/cumin/job.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/job.py 2008-09-05 17:13:20 UTC (rev 2420)
+++ mgmt/trunk/cumin/python/cumin/job.py 2008-09-05 17:13:53 UTC (rev 2421)
@@ -182,7 +182,7 @@
self.__remove = JobRemove(app, "jobRemove")
self.add_mode(self.__remove)
- self.__edit_ads = JobEditAds(app, "editads")
+ self.__edit_ads = JobAdsEditor(app, "editads")
self.add_mode(self.__edit_ads)
self.__scheduler = SchedulerFrame(app, "scheduler")
@@ -297,34 +297,30 @@
self.add_child(self.__tabs)
#self.__tabs.add_tab(JobStats(app, "stats"))
- self.__tabs.add_tab(JobAds(app, "jobads"))
+ self.__tabs.add_tab(JobAdsViewer(app, "jobads"))
self.__tabs.add_tab(JobOutput(app, "output"))
self.__tabs.add_tab(SystemSet(app, "systems"))
self.__tabs.add_tab(CuminDetails(app, "details"))
-class JobAds(Widget):
- def __init__(self, app, name):
- super(JobAds, self).__init__(app, name)
- props = JobAdsViewer(app, "properties")
- self.add_child(props)
-
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, job):
- return "Ad"
-
class JobAdsSet(PropertySet):
def __init__(self, app, name):
super(JobAdsSet, self).__init__(app, name, )
# self.got_data = False
- self.item_renderer = JobPropertyRenderer(self, "ad_html")
def get_args(self, session):
return self.frame.get_args(session)
def do_get_items(self, session, job):
+ items = self.items.get(session)
+ if not items:
+ items = self.gen_items(session, job)
+ # cache the items
+ self.items.set(session, items)
+
+ return items
+
+ def gen_items(self, session, job):
# def completion(status, args=None):
# self.got_data = True
@@ -414,41 +410,14 @@
u'Out': u'/dev/null'}
cls = self.app.model.get_class_by_object(job)
- keys = ads.keys()
- keys.sort()
- return [[x, ads[x], cls] for x in keys]
-class JobEditAds(CuminForm, JobAdsSet):
- def __init__(self, app, name):
- super(JobEditAds, self).__init__(app, name)
+ # list of dictionaries
+ # each disctionary has:
+ # name:, value:, type: [, error:] [, property:] [,path:]
+ return [self.gen_item(x, ads[x], cls) for x in ads]
- # the parameter that will hold all the field values
- self.ads = DictParameter(app, "params")
- self.add_parameter(self.ads)
- self.add_form_parameter(self.ads)
-
- self.item_renderer = EditablePropertyRenderer(self, "property_html")
-
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, job):
- return "Ad"
-
- def do_get_items(self, session, job):
- cls = self.app.model.get_class_by_object(job)
- ads = self.ads.get(session)
- if len(ads):
- keys = ads.keys()
- keys.sort()
- return [self.gen_item(x, ads[x]["value"], cls,
dtype=ads[x]["type"], error=ads[x]) for x in keys]
- else:
- items = super(JobEditAds,self).do_get_items(session, job)
- return [self.gen_item(x[0], x[1], cls) for x in items]
-
- def gen_item(self, name, value, cls, dtype=None, error=None):
+ def gen_item(self, name, value, cls, path=None, dtype=None, error=None):
idict = dict()
- ilist = list()
idict["name"] = name
idict["value"] = value
if dtype:
@@ -465,13 +434,122 @@
if name in cls.ad_properties_by_name:
idict["property"] = cls.ad_properties_by_name[name]
- ilist.append(idict)
- ilist.append(self.ads.path)
- return ilist
+ if path:
+ idict["path"] = path
+ return idict
def get_type(self, value):
return isinstance(value, int) and "number" or "string"
+class JobPropertyRenderer(TemplateRenderer):
+ def render_title(self, session, item):
+ title = item["name"]
+ if "property" in item:
+ property = item["property"]
+ if property.title:
+ title = property.get_title(session)
+ return escape_amp(title)
+
+ def render_value(self, session, item):
+ value = item["value"]
+ if "property" in item:
+ property = item["property"]
+ if property.renderer:
+ value = property.renderer(session, value)
+ return escape_amp(value)
+
+ def render_inline_help(self, session, item):
+ if "property" in item:
+ property = item["property"]
+ return property.description
+
+class JobAdsViewer(JobAdsSet):
+ def __init__(self, app, name):
+ super(JobAdsViewer, self).__init__(app, name)
+
+ self.group_tmpl = Template(self, "group_html")
+ self.item_renderer = JobPropertyRenderer(self, "property_html")
+
+ def get_args(self, session):
+ return self.frame.get_args(session)
+
+ def render_title(self, session, job):
+ return "Properties"
+
+ def do_get_items(self, session, args):
+ job = args[0]
+ group = args[1]
+ all_items = super(JobAdsViewer, self).do_get_items(session, job)
+ group_items = list()
+ for item in all_items:
+ if "property" in item:
+ property = item["property"]
+ item_group = property.group
+ else:
+ item_group = "Other"
+ if item_group == group:
+ group_items.append(item)
+
+ return group_items
+
+ def render_properties(self, session, *args):
+ items = self.do_get_items(session, *args)
+ writer = Writer()
+
+ for item in items:
+ self.item_renderer.render(writer, session, item)
+
+ return writer.to_string()
+
+ def render_edit_ads_url(self, session, job):
+ branch = session.branch()
+ self.frame.show_ads_edit(branch)
+ return branch.marshal()
+
+ def render_groups(self, session, job):
+ groups = self.app.model.get_ad_groups()
+ writer = Writer()
+ for group in groups:
+ self.group_tmpl.render(writer, session, (job, group,))
+ return writer.to_string()
+
+ def render_group_name(self, session, args):
+ return args[1]
+
+class JobAdsEditor(CuminForm, JobAdsViewer):
+ def __init__(self, app, name):
+ super(JobAdsEditor, self).__init__(app, name)
+
+ # the parameter that will hold all the field values
+ self.ads = DictParameter(app, "params")
+ self.add_parameter(self.ads)
+ self.add_form_parameter(self.ads)
+
+ self.item_renderer = EditablePropertyRenderer(self, "property_html")
+
+ def do_get_items(self, session, args):
+ job = args[0]
+ group = args[1]
+ cls = self.app.model.get_class_by_object(job)
+ ads = self.ads.get(session)
+ if len(ads):
+ return [self.gen_item(x, ads[x]["value"], cls, path=self.ads.path,
+ dtype=ads[x]["type"], error=ads[x]) for x in
ads
+ if self.is_group(x, cls, group)]
+ else:
+ items = super(JobAdsEditor, self).do_get_items(session, args)
+ for item in items:
+ item["path"] = self.ads.path
+ return items
+
+ def is_group(self, name, cls, group):
+ if name in cls.ad_properties_by_name:
+ property = cls.ad_properties_by_name[name]
+ item_group = property.group
+ else:
+ item_group = "Other"
+ return item_group == group
+
def process_submit(self, session, job):
ads = self.ads.get(session)
errors = False
@@ -498,50 +576,6 @@
action.invoke(job, just_ads)
self.process_cancel(session, job)
- def process_cancel(self, session, job):
- self.ads.clear()
- super(JobEditAds, self).process_cancel(session, job)
-
-class JobPropertyRenderer(TemplateRenderer):
- def render_ad_title(self, session, prop):
- return escape_amp(prop[0])
-
- def render_ad_value(self, session, prop):
- name, value, props = self.decode_props(prop)
- if props and props.renderer:
- value = props.renderer(session, value)
- return escape_amp(value)
-
- def render_ad_help(self, session, prop):
- name, value, props = self.decode_props(prop)
- if props and props.description:
- return props.description
-
- def decode_props(self, prop):
- name = prop[0]
- value = prop[1]
- cls = prop[2]
- if name in cls.ad_properties_by_name:
- props = cls.ad_properties_by_name[name]
- else:
- props = None
- return name, value, props
-
-class JobAdsViewer(JobAdsSet):
- def __init__(self, app, name):
- super(JobAdsViewer, self).__init__(app, name)
-
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def do_get_items(self, session, job):
- return super(JobAdsViewer, self).do_get_items(session, job)
-
- def render_edit_ads_url(self, session, job):
- branch = session.branch()
- self.frame.show_ads_edit(branch)
- return branch.marshal()
-
class JobOutput(TabbedModeSet):
def __init__(self, app, name):
super(JobOutput, self).__init__(app, name)
Modified: mgmt/trunk/cumin/python/cumin/job.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/job.strings 2008-09-05 17:13:20 UTC (rev 2420)
+++ mgmt/trunk/cumin/python/cumin/job.strings 2008-09-05 17:13:53 UTC (rev 2421)
@@ -111,39 +111,46 @@
[JobAdsViewer.html]
<ul class="actions">
- <li><a class="nav" href="{edit_ads_url}">Edit Job
Ad</a></li>
+ <li><a class="nav" href="{edit_ads_url}">Edit
Properties</a></li>
</ul>
<table class="CuminDetails">
<tbody>
<tr>
<td>
- <h2>Ad</h2>
- <table class="PropertySet">
- <thead>
- <tr>
- <th style="width: 33%;">Name</th>
- <th style="width: 33%;">Value</th>
- <th style="width: 33%;"> </th>
- </tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
+ <h2>Properties</h2>
+ {groups}
</td>
</tr>
</tbody>
</table>
<ul class="actions">
- <li><a class="nav" href="{edit_ads_url}">Edit Job
Ad</a></li>
+ <li><a class="nav" href="{edit_ads_url}">Edit
Properties</a></li>
</ul>
-[JobAdsViewer.ad_html]
+[JobAdsViewer.group_html]
+<div class="sactions">
+ <h2>{group_name}</h2>
+</div>
+<table class="PropertySet">
+ <thead>
+ <tr>
+ <th style="width: 33%;">Name</th>
+ <th style="width: 33%;">Value</th>
+ <th style="width: 33%;"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ {properties}
+ </tbody>
+</table>
+
+
+[JobAdsViewer.property_html]
<tr>
- <th>{ad_title}</th><td>{ad_value}</td><td>{ad_help}</td>
+ <th>{title}</th><td>{value}</td><td>{inline_help}</td>
</tr>
-
-
-[JobEditAds.css]
+[JobAdsEditor.css]
div.inline_help {
float: right;
}
@@ -152,29 +159,20 @@
display: inline;
}
-[JobEditAds.html]
+[JobAdsEditor.html]
<form id="{id}" class="mform editform" method="post"
action="?">
<div class="inline_help">
<h2>Legend</h2>
- <span class="edit_string">String input expected</span>
<span class="edit_number">Numeric input expected</span>
+ <span class="edit_string">String input expected</span>
</div>
{help} {submit} {cancel}
-<table class="CuminDetails">
+<table class="CuminDetails Editable">
<tbody>
<tr>
<td>
- <h2>Edit Job Ad</h2>
- <table class="PropertySet Editable">
- <thead>
- <tr>
- <th style="width: 33%;">Name</th>
- <th style="width: 33%;">Value</th>
- <th style="width: 33%;"> </th>
- </tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
+ <h2>Properties</h2>
+ {groups}
</td>
</tr>
</tbody>
@@ -183,7 +181,4 @@
<div>{hidden_inputs}</div>
</form>
-[JobEditAds.property_html]
-<tr>
- <th>{title}</th><td>{value}</td><td>{inline_help}</td>
-</tr>
+
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 17:13:20 UTC (rev 2420)
+++ mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 17:13:53 UTC (rev 2421)
@@ -67,6 +67,9 @@
self.classes.append(cls)
setattr(self, cls.cumin_name, cls)
+ def get_ad_groups(self):
+ return AdProperty.get_ad_groups()
+
def get_class_by_object(self, mint_object):
for cls in self.classes:
if cls.mint_class is mint_object.__class__:
@@ -102,18 +105,32 @@
return self.app.main_page.show_main(session)
class AdProperty(object):
+ groups = ["Main", "Condor Info", "Command Info",
"Other"]
+
def __init__(self, cls, name):
self.cumin_model = cls.cumin_model
self.cumin_class = cls
self.description = None
self.example = None
+ self.group = "Main"
self.name = name
self.renderer = None
+ self.title = None
self.writable = True
self.cumin_class.add_ad_property(self)
+ def get_title(self, session):
+ if self.title:
+ return self.title
+ else:
+ return self.name
+
+ @classmethod
+ def get_ad_groups(cls):
+ return cls.groups
+
class CuminProperty(object):
def __init__(self, cls, name):
self.cumin_model = cls.cumin_model
@@ -368,10 +385,6 @@
self.ad_properties.append(prop)
self.ad_properties_by_name[prop.name] = prop
- def add_ad_property(self, prop):
- self.ad_properties.append(prop)
- self.ad_properties_by_name[prop.name] = prop
-
def add_stat(self, stat):
self.stats.append(stat)
setattr(self, stat.name, stat)
@@ -1462,30 +1475,57 @@
def __init__(self, model):
super(CuminJob, self).__init__(model, "job", Job, JobStats)
- prop = CuminProperty(self, "AccountingGroup")
- prop.title = "Group"
- prop.summary = True
+ ### Main Group
+ prop = self.JobStatusProperty(self, "JobStatus")
+ prop.description = "The current job status"
+ prop.renderer = prop.render_status
+ prop.title = "Job Status"
+ prop.writable = False
+ prop = AdProperty(self, "Owner")
+ prop.writable = False
+
+ prop = AdProperty(self, "BufferBlockSize")
+ prop.example = "32768"
+
+ ### Condor Info Group
prop = AdProperty(self, "CondorVersion")
+ prop.group = "Condor Info"
prop.writable = False
prop = AdProperty(self, "CondorPlatform")
+ prop.group = "Condor Info"
prop.writable = False
- prop = AdProperty(self, "Owner")
- prop.writable = False
-
+ ### Command Info Group
prop = AdProperty(self, "Args")
prop.description = "Arguments passed to job Cmd"
+ prop.group = "Command Info"
- prop = AdProperty(self, "BufferBlockSize")
- prop.example = "<span
class=\"prop_example\">32768</span>"
+ prop = AdProperty(self, "Cmd")
+ prop.description = "Command that will run the job"
+ prop.group = "Command Info"
+ prop.title = "Command"
- prop = self.JobStatusProperty(self, "JobStatus")
- prop.writable = False
- prop.renderer = prop.render_status
- prop.description = "The current job status"
+ prop = AdProperty(self, "In")
+ prop.description = "Command Input"
+ prop.group = "Command Info"
+ prop = AdProperty(self, "Iwd")
+ prop.description = "Command Input Working Directory"
+ prop.group = "Command Info"
+ prop.title = "Working Directory"
+
+ prop = AdProperty(self, "Out")
+ prop.description = "Where the output will be stored"
+ prop.example = "'/dev/null' or '~/logs/'"
+ prop.group = "Command Info"
+
+ ######## Properties
+ prop = CuminProperty(self, "AccountingGroup")
+ prop.summary = True
+ prop.title = "Group"
+
prop = self.SchedulerProperty(self, "scheduler")
prop.title = "Scheduler"
prop.summary = True
@@ -1543,6 +1583,7 @@
prop = CuminProperty(self, "HoldReason")
prop.title = "Hold Reason"
+ ######## Actions
action = self.Hold(self, "hold")
action.summary = True
@@ -1553,6 +1594,7 @@
action.summary = True
action = self.SaveAd(self, "savead")
+ action.navigable = False
def get_title(self, session):
return "Job"
@@ -1587,11 +1629,17 @@
class SchedulerProperty(CuminProperty):
def value(self, session, job):
- scheduler = job.scheduler
branch = session.branch()
frame = self.cumin_class.get_pool_frame(branch)
- frame.show_scheduler(branch, scheduler)
- return scheduler and escape_amp(fmt_olink(branch, scheduler,
name=scheduler.Name))
+ try:
+ scheduler = job.scheduler
+ frame.show_scheduler(branch, scheduler)
+ except:
+ scheduler = job
+ scheduler.Name = "Unavailable"
+ frame.show_job(branch, job)
+
+ return escape_amp(fmt_olink(branch, scheduler, name=scheduler.Name))
class Hold(CuminAction):
def show(self, session, job):
@@ -1627,6 +1675,9 @@
job.remove(self.cumin_model.data, completion)
class SaveAd(CuminAction):
+ def show(self, session, job):
+ pass
+
def get_title(self, session):
return "Save Ad for"