Feedback on role enforcement patch and a pending commit
by Trevor McKay
Hello all,
I played with the patch yesterday, and I think it's close to something
we can distribute in general from trunk. Here are few items, in no
particular order. Please share your thoughts.
1) I prototyped a redirect solution, about to commit to the branch. It
specifies a fallback page per group in the xml file. When a user
touches an unauthorized widget, the fallback page is read based on the
group and a redirect is sent. Not much code and it seems to work well
-- it solves the "login" issue for groups not authorized to see
index.html, which was the biggest issue. Let me know what you think.
(this can be improved slightly if the redirect from a login form looks
up the user's group first, before going straight to index.html, so we
don't get a double redirect, but that is minor)
2) I wonder about the naming convention used in the xml file. There is
already an internal naming convention that is used within a page. It
names widgets based on their placement in the hierarchy. It's used
internally in a few places to navigate, and it's used in generating URLs
(page_widgets_by_path[] I think is an example of where it's stored).
I think it would be good if we could use the internal naming convention,
so we don't have multiple ways to name widgets. Also, naming based on
placement may be more natural for authorization. Naming based on module
and class doesn't necessarily map well to authorization -- then
placement in modules of classes becomes very important.
The current naming convention may have to be extended to the "app" level
so that it could be accessed from everywhere.
This is something to investigate.
3) I had an idea on processing the mapping differently. Right now, we
have to find a list of regular expressions for a user based on group(s)
and then search for a widget across all of those regular expressions
until one is matched or all have been tested.
What if we had a pre-processing step on initialization of cumin-web,
like we do for the rosemary module or other things in Cumin? What if
when each widget runs __init__, it looks up it's list of authorized
groups and stores it in self.authorized_groups. Then, to check
authorization for a widget we have just a simple dictionary lookup on a
small group list. Very fast.
Also, this fixes the "all wooly widgets are authorized" problem. We
just treat an empty self.authorized list as "OK".
I may go ahead and try this in a local branch to see how it works.
Best,
Trev
12 years, 1 month
r5263 - in branches/roles: cumin/instance/etc cumin/python/cumin wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-03-22 12:10:56 +0000 (Thu, 22 Mar 2012)
New Revision: 5263
Modified:
branches/roles/cumin/instance/etc/cumin.conf
branches/roles/cumin/python/cumin/authorize.py
branches/roles/cumin/python/cumin/main.py
branches/roles/cumin/python/cumin/widgets.py
branches/roles/wooly/python/wooly/__init__.py
branches/roles/wooly/python/wooly/pages.py
Log:
Prototype a solution for redirects when unauthorized widgets are accessed.
Modified: branches/roles/cumin/instance/etc/cumin.conf
===================================================================
--- branches/roles/cumin/instance/etc/cumin.conf 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/cumin/instance/etc/cumin.conf 2012-03-22 12:10:56 UTC (rev 5263)
@@ -2,7 +2,7 @@
database: dbname=cumin user=cumin host=localhost
#database: dbname=cumin user=cumin host=172.22.88.13 port=5432 password=cumin
#brokers: cumin/rasca@172.22.88.13:5672
-debug: True
+# debug: True
[web]
# host: localhost
Modified: branches/roles/cumin/python/cumin/authorize.py
===================================================================
--- branches/roles/cumin/python/cumin/authorize.py 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/cumin/python/cumin/authorize.py 2012-03-22 12:10:56 UTC (rev 5263)
@@ -16,6 +16,7 @@
log.info("Initializing %s", self.__class__.__name__)
regs = []
self.mapping = {}
+ self.fallbacks = {}
self.filepath = None
def __repr__(self):
@@ -28,14 +29,17 @@
for gacc in acctree.getiterator('GroupAccess'):
gkey = gacc.attrib["name"]
self.mapping[gkey] = []
+ self.fallbacks[gkey] = "index.html"
log.debug("Adding group element %s" , gkey)
for child in gacc.getchildren():
if child.tag == "WidgetAccess":
wa = child.attrib['reg']
self.mapping[gkey].append(re.compile(wa))
- log.debug("Addig widget access %s for %s", wa, gkey)
+ log.debug("Adding widget access %s for %s", wa, gkey)
elif child.tag == "SubGroupAccess":
merges[gkey] = child.attrib["name"]
+ elif child.tag == "FallbackPage":
+ self.fallbacks[gkey] = child.attrib["name"]
else:
log.error("Illegal access tag %s in tree", child.tag)
#TODO: handle adding properly
@@ -51,6 +55,12 @@
return False
return False
+ def find_fallback(self, group):
+ try:
+ return self.fallbacks[group]
+ except KeyError:
+ return None
+
class CuminAuthorizator(object):
def __init__(self, app):
self.app = app
@@ -68,6 +78,19 @@
log.error("Path for access files does not exist!")
log.info("NODULES %s", modules)
+ def find_fallback(self, web_session):
+ # Find a fallback page for the current login session.
+ # If the user is part of multiple groups, just pick the
+ # first one. There may be a way to make a priority scheme here,
+ # but does it really matter?
+ try:
+ group = web_session.client_session.attributes['login_session'].group
+ except KeyError:
+ group = "nogroup"
+ if type(group) == type([]):
+ group = group[0]
+ return self.accmap.find_fallback(group)
+
def authorize(self,web_session, widget_name):
try:
group = web_session.client_session.attributes['login_session'].group
Modified: branches/roles/cumin/python/cumin/main.py
===================================================================
--- branches/roles/cumin/python/cumin/main.py 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/cumin/python/cumin/main.py 2012-03-22 12:10:56 UTC (rev 5263)
@@ -62,6 +62,7 @@
self.authorizator = CuminAuthorizator(self)
self.authorize_cb = self.authorizator.authorize
+ self.fallback_cb = self.authorizator.find_fallback
self.tasks = list()
Modified: branches/roles/cumin/python/cumin/widgets.py
===================================================================
--- branches/roles/cumin/python/cumin/widgets.py 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/cumin/python/cumin/widgets.py 2012-03-22 12:10:56 UTC (rev 5263)
@@ -1313,20 +1313,27 @@
self.error_tmpl = WidgetTemplate(self, "error_html")
self.not_found_tmpl = WidgetTemplate(self, "not_found_html")
- def do_process(self, session):
+ def _redirect_to_login(self, session):
session.cursor = self.app.database.get_read_cursor()
-
if not self.authorized(session):
page = self.app.login_page
-
sess = Session(page)
page.origin.set(sess, session.marshal())
-
self.redirect.set(session, sess.marshal())
+ return True
+ return False
- return
+ def redirect_on_not_authorized(self, session):
+ # If the user is not logged in, then it doesn't have a
+ # a group identity yet. Check to see if we should
+ # redirect to the login page before looking for a
+ # valid page to redirect to based on group
+ if not self._redirect_to_login(session):
+ super(CuminPage, self).redirect_on_not_authorized(session)
- super(CuminPage, self).do_process(session)
+ def do_process(self, session):
+ if not self._redirect_to_login(session):
+ super(CuminPage, self).do_process(session)
def authorized(self, session):
if not self.protected:
Modified: branches/roles/wooly/python/wooly/__init__.py
===================================================================
--- branches/roles/wooly/python/wooly/__init__.py 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/wooly/python/wooly/__init__.py 2012-03-22 12:10:56 UTC (rev 5263)
@@ -287,26 +287,31 @@
for child in self.children:
child.save_parameters(session, params)
+ def redirect_on_not_authorized(self, session):
+ # Give an opportunity to redirect to a valid page
+ # when a user is not authorized for this widget.
+ pass
+
def process(self, session, *args):
#TODO: cleanup
log.debug("WOOLY PROCESS: %s", self.my_name)
if not self.app.authorize_cb(session, self.my_name):
- return
+ self.redirect_on_not_authorized(session)
+ else:
+ if self.update_enabled:
+ self.page.enable_update(session, self)
- if self.update_enabled:
- self.page.enable_update(session, self)
+ if self.defer_enabled:
+ self.page.enable_defer(session, self)
- if self.defer_enabled:
- self.page.enable_defer(session, self)
+ if self.app.debug:
+ profile = self.page.profile.get(session)
- if self.app.debug:
- profile = self.page.profile.get(session)
+ call = ProcessCall(profile, self, args)
+ call.do(session)
+ else:
+ self.do_process(session, *args)
- call = ProcessCall(profile, self, args)
- call.do(session)
- else:
- self.do_process(session, *args)
-
def do_process(self, session, *args):
for child in self.children:
child.process(session)
Modified: branches/roles/wooly/python/wooly/pages.py
===================================================================
--- branches/roles/wooly/python/wooly/pages.py 2012-03-21 20:10:53 UTC (rev 5262)
+++ branches/roles/wooly/python/wooly/pages.py 2012-03-22 12:10:56 UTC (rev 5263)
@@ -149,6 +149,14 @@
return sess.marshal()
+ def redirect_on_not_authorized(self, session):
+ fallback_page = self.app.fallback_cb(session)
+ if fallback_page in self.app.pages_by_name:
+ log.debug("Not authorized, redirecting to %s", fallback_page)
+ page = self.app.pages_by_name[fallback_page]
+ sess = Session(page)
+ self.redirect.set(session, sess.marshal())
+
def do_process(self, session):
self.update_script.process(session)
self.defer_script.process(session)
12 years, 1 month
r5262 - trunk/cumin/resources
by croberts@fedoraproject.org
Author: croberts
Date: 2012-03-21 20:10:53 +0000 (Wed, 21 Mar 2012)
New Revision: 5262
Removed:
trunk/cumin/resources/slots.swf
trunk/cumin/resources/slotvis-Available.png
trunk/cumin/resources/slotvis-Paused.png
trunk/cumin/resources/slotvis-Running.png
trunk/cumin/resources/slotvis-Starting.png
trunk/cumin/resources/slotvis-Stopping.png
trunk/cumin/resources/slotvis-Unavailable.png
trunk/cumin/resources/slotvis.js
trunk/cumin/resources/swfobject.js
Log:
Per BZ 805029, more code cleanup following the slotvis removal.
Deleted: trunk/cumin/resources/slots.swf
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Available.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Paused.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Running.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Starting.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Stopping.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis-Unavailable.png
===================================================================
(Binary files differ)
Deleted: trunk/cumin/resources/slotvis.js
===================================================================
--- trunk/cumin/resources/slotvis.js 2012-03-21 20:09:53 UTC (rev 5261)
+++ trunk/cumin/resources/slotvis.js 2012-03-21 20:10:53 UTC (rev 5262)
@@ -1,825 +0,0 @@
-var vis;
-
-(function() {
- vis = new Visualization();
-
- var slot_clip_left;
- var slot_clip_top;
- var slot_zoom;
- var slot_last_index;
- var slot_info_timer;
- var slot_hover_timer;
- var slot_png_timer;
- var slot_zoom_initialized;
- var slot_center_index;
-
- function Visualization() {
- slot_clip_left = 0;
- slot_clip_top = 0;
- slot_zoom = 1;
- slot_last_index = -1;
- slot_info_timer = null;
- slot_hover_timer = null;
- slot_png_timer = null;
- slot_zoom_initialized = false;
- slot_center_index = -1;
-
- this.notify = function(fullpage, size) {
- slot_clip_size = size;
- this.img_loaded(document.images[slot_current_id]);
- }
- this.pan_left = function () {
- if (slot_clip_left == 0) return;
- var now = new Date();
- animate_pan(slot_clip_left, Math.min(Math.floor(slot_clip_size / 1.1), -slot_clip_left), (now-0), "slot_clip_left");
- }
-
- this.pan_right = function () {
- var to_pan = Math.floor(slot_clip_size / 1.1);
- if (slot_clip_left - slot_clip_size - to_pan < -slot_map_info.width) {
- to_pan = slot_map_info.width - slot_clip_size + slot_clip_left;
- }
- var now = new Date();
- animate_pan(slot_clip_left, -to_pan, (now-0), "slot_clip_left");
- }
-
- this.pan_up = function () {
- if (slot_clip_top == 0) return;
- var now = new Date();
- animate_pan(slot_clip_top, Math.min(Math.floor(slot_clip_size / 1.1), -slot_clip_top), (now-0), "slot_clip_top");
- }
-
- this.pan_down = function () {
- if (slot_map_info.height < slot_clip_size) return;
-
- var to_pan = Math.floor(slot_clip_size / 1.1);
- if (slot_clip_top - slot_clip_size - to_pan < -slot_map_info.height) {
- to_pan = slot_map_info.height - slot_clip_size + slot_clip_top;
- }
- var now = new Date();
- animate_pan(slot_clip_top, -to_pan, (now-0), "slot_clip_top");
- }
-
-
- // in case server stops and then restarts, reget the images
- this.img_error = function (oImg) {
- stop_auto_updates();
- var oZooming = document.getElementById("slot_zooming");
- if (oZooming) {
- oZooming.style.display = "none";
- }
- oImg.style.visibility = "hidden"; // hide broken image indicator
- slot_map_info.size = 0;
- slot_map_info.width = 1;
- slot_map_info.height = 1;
- slot_map_info.rows = 1;
- slot_map_info.cols = 1;
- slot_map_info.count = 0;
- slot_png_timer = setInterval(update_png, 10000);
- }
-
- this.img_loaded = function (oImg) {
- stop_auto_updates();
- var oZooming = document.getElementById("slot_zooming");
- if (oZooming) {
- oZooming.style.display = "none";
- }
-
- if (oImg) {
- oImg.style.visibility = "visible";
- slot_cookie_info();
- oImg.width = slot_map_info.width;
- oImg.height = slot_map_info.height;
- set_pan("slot_panup", "width", slot_map_info.size * slot_map_info.cols, this.pan_up);
- set_pan("slot_pandown", "width", slot_map_info.size * slot_map_info.cols, this.pan_down);
- set_pan("slot_panleft", "height", slot_map_info.size * slot_map_info.rows, this.pan_left);
- set_pan("slot_panright", "height", slot_map_info.size * slot_map_info.rows, this.pan_right);
-
- var oMap = document.getElementById(slot_current_id);
- if (oMap) {
- oMap.style.width = Math.min(oImg.width, slot_clip_size) + "px";
- oMap.style.height = Math.min(oImg.height, slot_clip_size) + "px";
- if ((slot_map_info.size * slot_map_info.rows < slot_clip_size) &&
- (slot_map_info.size * slot_map_info.cols < slot_clip_size))
- oMap.style.borderColor = "transparent";
- else
- oMap.style.borderColor = "#CCCCCC";
-
- }
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- oGlass.style.width = Math.min(oImg.width, slot_clip_size) + "px";
- oGlass.style.height = Math.min(oImg.height, slot_clip_size) + "px";
- }
- if (!slot_zoom_initialized)
- initialize_zoom();
-
- animate_zoom_to(slot_zoom);
- var oControls = document.getElementById("slot_controls");
- if (oControls) {
- var oMap = document.getElementById(slot_current_id);
- oControls.style.left = (oMap.offsetLeft + oMap.offsetWidth - oControls.offsetWidth) + "px";
- //oControls.style.left = (420 - oControls.offsetWidth) + "px";
- }
- refire_info();
- }
- center_on_index();
- draw_clipped();
- slot_png_timer = setInterval(update_png, 6000);
- }
-
- this.upGlass = function (e) {
- if (!e) var e = window.event;
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- if (oGlass.dragging) {
- oGlass.dragging = false;
- }
- }
- }
-
- this.moveGlass = function (e) {
- if (slot_map_info.size == 0) return;
- if (!e) var e = window.event;
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- if (oGlass.dragging) {
- var posxy = get_event_pos(e);
- if ((posxy.x - oGlass.down_pos.x > 0) || (posxy.y - oGlass.down_pos.y > 0))
- oGlass.down_pos = {x: posxy.x - slot_clip_left, y: posxy.y - slot_clip_top};
-
- slot_clip_left = Math.min(posxy.x - oGlass.down_pos.x, 0);
- slot_clip_top = Math.min(posxy.y - oGlass.down_pos.y, 0);
- oGlass.drug = true;
-
- draw_clipped();
- if (e.preventDefault)
- e.preventDefault();
- return false;
- }
- }
-
- var rpos = get_relative_event_pos(e);
- if (rpos) {
- get_slot_info(rpos.x, rpos.y);
- }
- }
-
- this.downGlass = function (e) {
- if (!e) var e = window.event;
-
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- oGlass.dragging = true;
- var posxy = get_event_pos(e);
- oGlass.down_pos = {x: posxy.x - slot_clip_left, y: posxy.y - slot_clip_top};
- clear_hover();
- hide_info();
- }
- return false;
- }
-
- this.outGlass = function outGlass(e) {
- if (!e) var e = window.event;
- clear_hover();
- hide_info();
- }
-
- this.zoom_in_slots = function (posxy) {
- if (slot_zoom >= get_max_zoom()) return;
- var click_info = vis.get_index(posxy.x, posxy.y);
- slot_center_index = click_info.index;
- do_zoom(slot_zoom + 1);
- }
-
- this.fire_slot_info = function (index) {
- slot_last_index = index;
- slot_info_timer = null;
- do_info_request(index);
- }
-
- this.get_index = function (x, y) {
- var width = slot_map_info.size;
- var pngrow = Math.floor((y - slot_clip_top) / width);
- var pngcol = Math.floor((x - slot_clip_left) / width);
-
- if ((pngcol < slot_map_info.cols) && (pngrow < slot_map_info.rows)) {
- var index = pngrow * slot_map_info.cols + pngcol;
-
- if (index < slot_map_info.count)
- return {"index": index, "row": pngrow, "col": pngcol};
- }
-
- return null;
- }
-
- }
-
- function slot_zoom_to(e) {
- if (!e) var e = window.event;
- var targ = get_event_target(e);
- var level = parseInt(targ.level, 10);
-
- get_center_index();
- do_zoom(level);
-
- if (e.stopPropagation)
- e.stopPropagation()
- else if (e.cancelBubble)
- e.cancelBubble = true;
- }
-
- function do_zoom(level) {
- var old_zoom = slot_zoom;
- slot_zoom = level;
-
- stop_auto_updates();
- var oZooming = document.getElementById("slot_zooming");
- if (oZooming) {
- oZooming.style.display = "block";
- //var oMap = document.getElementById(slot_current_id);
- //if (oMap) {
- // oZooming.style.width = oMap.offsetWidth + "px";
- //}
- }
- var oImg = document.images[slot_current_id];
- if (oImg) {
- var src = oImg.src;
- var branch = wooly.session.branch(src);
- branch.zl = level;
- branch.zx = slot_clip_left;
- branch.zy = slot_clip_top;
- src = branch.marshal();
-
- src = cumin.refreshTime(src);
- oImg.src = src;
- }
-
- animate_zoom_to(level);
- return false;
- }
-
- function animate_zoom_to(level) {
- var oPos = document.getElementById("zoom_pos");
- if (oPos) {
- var original_x = oPos.offsetLeft;
- var now = new Date();
- var x_amount = ((level - 1) * 13) - original_x;
- animate_zoom_pos(original_x, (now-0), x_amount)
- }
- }
-
- function animate_zoom_pos(original_x, original_time, x_amount) {
- var oPos = document.getElementById("zoom_pos");
-
- if (oPos) {
- var now = new Date();
- var delta = (now - original_time) / 400.0;
- var partial = 1;
-
- if (delta < 1)
- partial = Math.sin(Math.PI/2 * delta);
-
- oPos.style.left = Math.floor(original_x + x_amount * partial) + "px";
-
- if (delta < 1) {
- setTimeout(function() {
- animate_zoom_pos(original_x, original_time, x_amount)
- }, 10);
- }
- }
- }
-
- function stop_auto_updates() {
- if (slot_png_timer) {
- clearInterval(slot_png_timer);
- slot_png_timer = null;
- }
- }
-
- function update_png() {
- stop_auto_updates();
- cumin.updateChart(slot_current_id, null);
- }
-
- function set_pan(id, which, value, fn) {
- var obj = document.getElementById(id);
- if (obj) {
- if (value <= slot_clip_size) {
- eval("obj.style." + which + " = '" + Math.min(value, slot_clip_size) + "px'");
- obj.style.visibility = "hidden";
- obj.onclick = null;
- } else {
- eval("obj.style." + which + " = '" + Math.min(value, slot_clip_size) + "px'");
- obj.style.visibility = "visible";
- obj.onclick = fn;
- }
- }
- }
-
- function slot_cookie_info() {
- var slot_info = get_cookie("slot_info");
- if (slot_info) {
- var vals = slot_info.split("|");
- if (vals.length == 6) {
- slot_map_info.size = parseInt(vals[0], 10);
- slot_map_info.width = parseInt(vals[1], 10);
- slot_map_info.height = parseInt(vals[2], 10);
- slot_map_info.count = parseInt(vals[3], 10);
- slot_map_info.rows = parseInt(vals[4], 10);
- slot_map_info.cols = parseInt(vals[5], 10);
- }
- }
- }
-
- function center_on_index() {
- if (slot_center_index == -1) return;
-
- var row = slot_center_index % slot_map_info.cols;
- var col = Math.floor(slot_center_index / slot_map_info.cols);
- var x = col * slot_map_info.size + slot_map_info.size / 2;
- var y = row * slot_map_info.size + slot_map_info.size / 2;
-
- var cl = (Math.min(slot_clip_size, slot_map_info.width) / 2) - x;
- var ct = (Math.min(slot_clip_size, slot_map_info.height) / 2) - y;
-
- if (slot_map_info.width + cl < slot_clip_size)
- cl = slot_clip_size - slot_map_info.width;
-
- if (slot_map_info.height + ct < slot_clip_size)
- ct = slot_clip_size - slot_map_info.height;
-
- if (cl > 0) cl = 0;
- if (ct > 0) ct = 0;
-
- slot_clip_left = Math.floor(cl);
- slot_clip_top = Math.floor(ct);
- slot_center_index = -1;
- }
-
- function get_center_index() {
- var rx = Math.min(slot_clip_size, slot_map_info.width) / 2;
- var ry = Math.min(slot_clip_size, slot_map_info.height) / 2;
-
- var click_info = vis.get_index(rx, ry);
- if (click_info)
- slot_center_index = click_info.index;
- }
-
- function get_max_zoom() {
- // allow to zoom until each slot is at least 28px wide
- if ((slot_map_info.size == 0) || (slot_zoom == 0))
- return 1;
- return Math.ceil(28 / (slot_map_info.size / slot_zoom));
- }
-
- function initialize_zoom() {
- var max_zoom = get_max_zoom();
- var oZoom = document.getElementById("zoom_levels");
- if ((oZoom) && (max_zoom > 1)) {
- var oDiv, oText, oNode;
- for (var i=0; i<max_zoom; i++) {
- var oDiv = document.createElement("div");
- if (i == 0) {
- oDiv.className = "zoom_first";
- oDiv.onclick = slot_zoom_to;
- oDiv.level = i+1;
- set_text(oDiv, (i+1)+ "", "zoom_node");
- } else if (i == max_zoom - 1) {
- oDiv.className = "zoom_last";
- oDiv.onclick = slot_zoom_to;
- oDiv.level = i+1;
- set_text(oDiv, i+1, "zoom_node_last");
- } else {
- oDiv.className = "zoom_middle_left";
- oDiv.onclick = slot_zoom_to;
- oDiv.level = i+1;
- oZoom.appendChild(oDiv);
- oDiv = document.createElement("div");
- oDiv.className = "zoom_middle_right";
- oDiv.onclick = slot_zoom_to;
- oDiv.level = i+1;
- set_text(oDiv, (i+1)+ "", "zoom_node");
- }
- oZoom.appendChild(oDiv);
- }
- } else {
- var oControls = document.getElementById("slot_controls");
- if (oControls) {
- oControls.style.display = "none";
- }
- }
- $("slot_visualization").style.display = "block";
- cumin.makeFullPageable($("slot_visualization"));
- slot_zoom_initialized = true;
-
- function set_text(odiv, text, className) {
- var oText = document.createElement("div");
- var oNode = document.createTextNode(text+"");
- oText.className = className;
- oText.appendChild(oNode);
- odiv.appendChild(oText);
- oText.onclick = slot_zoom_to;
- oText.level = text;
- }
- }
-
- function draw_clipped() {
-
- var clip_bottom;
- var clip_right;
- if (slot_map_info.width < slot_clip_size) {
- clip_bottom = slot_map_info.height;
- clip_right = slot_map_info.width;
- slot_clip_left = 0;
- slot_clip_top = 0;
- } else {
- var iZoom = slot_zoom;
- var clip_width = slot_clip_size;
- var clip_height = slot_clip_size;
- clip_bottom = clip_height - slot_clip_top;
- clip_right = clip_width - slot_clip_left;
-
- if (clip_right > slot_map_info.width) {
- slot_clip_left += (clip_right - slot_map_info.width);
- clip_right = slot_map_info.width;
- }
- if (clip_bottom > slot_map_info.height) {
- slot_clip_top = Math.min(clip_height - slot_map_info.height, 0);
- clip_bottom = slot_map_info.height;
- }
- }
-
- var oPng = document.getElementById("slot_png");
- if (oPng) {
- oPng.style.left = slot_clip_left + "px";
- oPng.style.top = slot_clip_top + "px";
- oPng.style.clip = "rect(" + (-slot_clip_top) + "px " + clip_right + "px " + clip_bottom + "px " + (-slot_clip_left) + "px)";
- }
- }
-
-
- function animate_pan(original_edge, move, timer, which) {
- var now = new Date();
- var delta = (now - timer) / 400.0;
- var expression = "=Math.floor(original_edge + move";
- if (delta < 1) {
- expression += " * Math.sin(Math.PI/2 * delta)";
- }
- expression += ")";
- eval(which + expression);
- draw_clipped();
- if (delta < 1)
- setTimeout( function () {animate_pan(original_edge, move, timer, which) }, 10);
-
- }
-
- function clear_hover() {
- if (slot_info_timer) {
- clearTimeout(slot_info_timer);
- slot_info_timer = null;
- slot_last_index = -1;
- }
- oHover = document.getElementById("slot_hover");
- if (oHover) {
- oHover.style.visibility = "hidden";
- }
- }
-
- function hide_info() {
- oInfo = $(slot_info_id);
- if (oInfo) {
- oInfo.style.visibility = "hidden";
- }
- slot_last_index = -1;
- }
-
- function get_slot_info(rx, ry) {
- var click_info = vis.get_index(rx, ry);
- if (click_info) {
- if (click_info.index != slot_last_index) {
- if (slot_info_timer) {
- clearTimeout(slot_info_timer);
- slot_info_timer = null;
- }
- if (slot_hover_timer) {
- clearTimeout(slot_hover_timer);
- slot_hover_timer = null;
- }
- slot_info_timer = setTimeout( function() { vis.fire_slot_info(click_info.index) }, 500);
- animate_hover(0, click_info.row, click_info.col);
- oInfo = $(slot_info_id);
- if (oInfo) {
- oInfo.style.display = "none";
- }
- }
- }
- }
-
- function animate_hover(leg, row, col) {
- var oHover = document.getElementById("slot_hover");
- if (oHover) {
- if (slot_hover_timer) {
- clearTimeout(slot_hover_timer);
- slot_hover_timer = null;
- }
- var width = slot_map_info.size;
- if (width <= 0) return;
- var rx = col * width + slot_clip_left;
- var ry = row * width + slot_clip_top;
- oHover.style.width = (width-4) + "px";
- oHover.style.height = (width-4) + "px";
-
- switch (leg) {
- case 0:
- oHover.style.left = rx + "px";
- oHover.style.top = ry + "px";
- oHover.style.borderColor = "red pink pink pink";
- oHover.style.visibility = "visible";
- if ((rx < 0) || (ry < 0) || (rx + width > slot_clip_size) || (ry + width > slot_clip_size)) {
- var cx = (rx < 0) ? rx : 0;
- var cy = (ry < 0) ? ry : 0;
- var cw = (rx + width > slot_clip_size) ? slot_clip_size - rx : width + 1;
- var ch = (ry + width > slot_clip_size) ? slot_clip_size - ry : width + 1;
- oHover.style.clip = "rect(" + (-cy) + "px " + (cw) + "px " + (ch) + "px " + (-cx) + "px)";
- } else {
- oHover.style.clip = "rect(0px " + (width+1) + "px " + (width+1) + "px 0px)";
- }
- slot_hover_timer = setTimeout( function() {animate_hover(1)}, 500/3);
- break;
- case 1: oHover.style.borderColor = "red red pink pink";
- slot_hover_timer = setTimeout( function() {animate_hover(2)}, 500/3);
- break;
- case 2: oHover.style.borderColor = "red red red pink";
- slot_hover_timer = setTimeout( function() {animate_hover(3)}, 500/3);
- break;
- case 3: oHover.style.borderColor = "red red red red";
- break;
- }
- }
- }
-
- function refire_info() {
- if (slot_last_index > -1) {
- do_info_request(slot_last_index)
- }
- }
-
- function do_info_request(index) {
- var branch = wooly.session.branch(slot_info_url);
- branch.session[slot_info_index] = index;
- var newreq = branch.marshal();
- wooly.setIntervalUpdate(newreq, got_slot_info, 0, {index: index});
- }
-
- function got_slot_info(xhtml, args) {
- if (slot_last_index == -1) return;
- var oInfo = $(slot_info_id);
- var slot_clicked = null;
- if (oInfo) {
- oInfo.style.display = "none";
- if (oInfo.slot_clicked) {
- slot_clicked = oInfo.slot_clicked;
- oInfo.slot_clicked = null;
- }
- }
- wooly.updatePage(xhtml);
- var oInfo = $(slot_info_id);
- if (oInfo) {
- oInfo.click_index = args.index;
- oInfo.slot_clicked = null;
- if (slot_clicked) {
- clicks.doClick(slot_clicked.x, slot_clicked.y);
- return;
- }
-
- document.body.appendChild(oInfo); // so position is absolute to entire page
-
- //oInfo.style.left = "-1000px";
- //oInfo.style.visibility = "hidden";
- oInfo.style.display = "block";
-
- var oMap = document.getElementById(slot_current_id);
- if (oMap) {
- var abs_pos = findPos(oMap);
-
- // top of clicked slot is here
- var y = Math.floor(args.index / slot_map_info.cols) * slot_map_info.size + slot_clip_top;
-
- // candidate pos for popup
- // just under the clicked slot
- var topUnder = (abs_pos.y + y) + Math.floor(slot_map_info.size * 1.5);
- var top = topUnder;
-
- // if off the bottom of the map
- if (topUnder + oInfo.offsetHeight > abs_pos.y + oMap.offsetHeight) {
- // position popup above clicked slot
- top = (abs_pos.y + y) - oInfo.offsetHeight - Math.floor(slot_map_info.size * .5);
- }
-
- // if off the top of the page
- if (top < 0) {
- // revert to under the item
- top = topUnder;
- }
-
- oInfo.style.top = top + "px";
- oInfo.style.left = abs_pos.x + "px";
- }
- oInfo.style.visibility = "visible";
- }
- }
-
-}())
-
-var clicks;
-
-(function() {
- clicks = new Clicks();
-
- function Clicks() {
- this.doubleclick_when = 0;
- this.click_when = 0;
- this.click_handle = null;
-
- this.doMouseDown = function(e) {
- if (!e) var e = window.event;
- var which = e.type;
- switch (which) {
- case "click":
- // If we've just had a doubleclick then ignore it
- if (hadDoubleClick()) return false;
- // Otherwise set timer to act. It may be preempted by a doubleclick.
- d = new Date();
- clicks.click_when = d.getTime();
- var rpos = get_relative_event_pos(e);
- if (rpos) {
- clicks.click_handle = setTimeout( function() {clicks.doClick(rpos.x, rpos.y)}, 250);
- break;
- }
- case "dblclick":
- doDoubleClick(e);
- break;
- default:
- }
- }
-
- this.doClick = function(x, y) {
- // preempt if DC occurred after original click.
- if (this.click_when - this.doubleclick_when <= 0) {
- return false;
- }
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- if (oGlass.drug) {
- oGlass.drug = false;
- return false;
- }
- }
- var click_info = vis.get_index(x, y);
- var oInfo = $(slot_info_id);
- if (oInfo && click_info) {
- if ((typeof oInfo.click_index != "undefined") &&
- (oInfo.click_index == click_info.index)) {
- // we already fetched the info for this slot
- var oInfoCellId = document.getElementById("slotInfo_id");
- if (oInfoCellId) {
- var slotid = oInfoCellId.innerHTML;
- if (slotid != "") {
- go_to_slot(slotid);
- return false;
- }
- }
- } else {
- // fetch the slot info so we can get the slot id
- oInfo.slot_clicked = {fetching: true, x: x, y: y};
- vis.fire_slot_info(click_info.index);
- }
- }
- }
- }
-
- function hadDoubleClick() {
- var d = new Date();
- var now = d.getTime();
- if ((now - this.doubleclick_when) < 100) {
- return true;
- }
- return false;
- }
-
- function doDoubleClick(e) {
- var now = new Date();
- clicks.doubleclick_when = now.getTime();
- if (clicks.click_handle != null) {
- clearTimeout(clicks.click_handle); // Clear pending Click
- clicks.click_handle = null;
- }
- if (!e) var e = window.event;
- var posxy = get_relative_event_pos(e);
- vis.zoom_in_slots(posxy);
- }
-}())
-
-function go_to_slot(id) {
- if (show_slot_url != "") {
- var branch = wooly.session.branch(show_slot_url);
- branch[branch.frame + ".id"] = id;
- window.location.href = branch.marshal();
- }
-}
-function vis_clicked(slot) {
- go_to_slot(slot);
-}
-/* generic get value from cookie */
-function get_cookie(name) {
- return get_value(document.cookie, name, ";");
-}
-
-/* generic get value from string */
-function get_value(s, name, sep) {
- var name_plus = name + "=";
- var crumbs = s.split(sep);
- // splitting to avoid false match on substring:
- // ex: bigfoo=duh;foo=blah;
- for(var i=0; i < crumbs.length; i++) {
- var c = crumbs[i];
- while (c.charAt(0) == ' ') {
- c = c.substring(1, c.length);
- }
-
- if (c.indexOf(name_plus) == 0) {
- return c.substring(name_plus.length,c.length);
- }
- }
- return null;
-}
-
-/* generic replace a value in a name=value; string */
-function replace_value(s, name, value, sep) {
- var name_index = s.indexOf(name+"=");
- if (name_index > -1) {
- var sep_index = s.indexOf(sep, name_index);
- if (sep_index == -1) { // end of string
- sep_index = s.length;
- }
- var s1 = s.substring(0, name_index + name.length + 1);
- var s2 = value + "";
- var s3 = s.substring(sep_index);
- return s1 + s2 + s3;
- }
- return s;
-}
-
-/* get the absolute position of something */
-function findPos(obj) {
- var curleft = curtop = 0;
- if (obj.offsetParent) {
- do {
- curleft += obj.offsetLeft;
- curtop += obj.offsetTop;
- } while (obj = obj.offsetParent);
- return {x: curleft, y: curtop};
- }
-}
-
-/* get the absolute event position */
-function get_event_pos(e) {
- if (e.pageX || e.pageY) {
- posx = e.pageX;
- posy = e.pageY;
- }
- else if (e.clientX || e.clientY) {
- posx = e.clientX + document.body.scrollLeft
- + document.documentElement.scrollLeft;
- posy = e.clientY + document.body.scrollTop
- + document.documentElement.scrollTop;
- }
- return {"x": posx, "y": posy};
-}
-
-/* find out what element the event was the event target */
-function get_event_target(e) {
- var targ = null;
- if (e.target)
- targ = e.target;
- else if (e.srcElement)
- targ = e.srcElement;
- if (targ.nodeType == 3) // avoid Safari textNode bug
- targ = targ.parentNode;
- return targ;
-}
-
-/* get the event position relatave to the event target */
-function get_relative_event_pos(e) {
- var targ = get_event_target(e);
- if (targ) {
- var pxy = findPos(targ);
- var posxy = get_event_pos(e);
-
- var rx = posxy.x - pxy.x - 2;
- var ry = posxy.y - pxy.y - 2;
- return {x: rx, y: ry};
- }
-}
-
Deleted: trunk/cumin/resources/swfobject.js
===================================================================
--- trunk/cumin/resources/swfobject.js 2012-03-21 20:09:53 UTC (rev 5261)
+++ trunk/cumin/resources/swfobject.js 2012-03-21 20:10:53 UTC (rev 5262)
@@ -1,4 +0,0 @@
-/* SWFObject v2.2 <http://code.google.com/p/swfobject/>
- is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
-*/
-var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
\ No newline at end of file
12 years, 1 month
r5261 - trunk/cumin/resources
by croberts@fedoraproject.org
Author: croberts
Date: 2012-03-21 20:09:53 +0000 (Wed, 21 Mar 2012)
New Revision: 5261
Modified:
trunk/cumin/resources/app.js
Log:
Per BZ 805029, more code cleanup following the slotvis removal.
Modified: trunk/cumin/resources/app.js
===================================================================
--- trunk/cumin/resources/app.js 2012-03-21 20:09:23 UTC (rev 5260)
+++ trunk/cumin/resources/app.js 2012-03-21 20:09:53 UTC (rev 5261)
@@ -373,12 +373,6 @@
return chart;
}
-/* Only needed for flash-based slotvis, can go away when that is changed */
-cumin.getFlashChart = function (id) {
- var chart = $(id+"_chart");
- return chart;
-}
-
function incrementChartSequence(chart) {
var src = chart.src;
var branch = wooly.session.branch(src);
12 years, 1 month
r5260 - in trunk/cumin/python/cumin: grid inventory
by croberts@fedoraproject.org
Author: croberts
Date: 2012-03-21 20:09:23 +0000 (Wed, 21 Mar 2012)
New Revision: 5260
Modified:
trunk/cumin/python/cumin/grid/main.py
trunk/cumin/python/cumin/grid/slot.py
trunk/cumin/python/cumin/grid/slot.strings
trunk/cumin/python/cumin/grid/slotvis.py
trunk/cumin/python/cumin/grid/slotvis.strings
trunk/cumin/python/cumin/inventory/main.py
trunk/cumin/python/cumin/inventory/system.py
trunk/cumin/python/cumin/inventory/system.strings
Log:
Per BZ 805029, code cleanup following the slotvis removal.
Modified: trunk/cumin/python/cumin/grid/main.py
===================================================================
--- trunk/cumin/python/cumin/grid/main.py 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/grid/main.py 2012-03-21 20:09:23 UTC (rev 5260)
@@ -5,8 +5,6 @@
from cumin import *
from cumin.objecttask import *
from cumin.util import *
-from cumin.grid.slot import SlotMapPage
-from cumin.grid.slotvis import PoolSlotFullPage
from submission import *
from pool import *
@@ -29,12 +27,6 @@
self.app.main_page.main.grid = self.frame
self.app.main_page.main.add_tab(self.frame)
- self.pool_slots_page = SlotMapPage(self.app, "poolslots.vis")
- self.app.add_page(self.pool_slots_page)
- self.pool_slots_fullpage = PoolSlotFullPage \
- (self.app, "poolslotsfull.vis")
- self.app.add_page(self.pool_slots_fullpage)
-
def init_test(self, test):
GridTest("grid", test)
Modified: trunk/cumin/python/cumin/grid/slot.py
===================================================================
--- trunk/cumin/python/cumin/grid/slot.py 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/grid/slot.py 2012-03-21 20:09:23 UTC (rev 5260)
@@ -21,22 +21,6 @@
super(SlotFrame, self).__init__(app, name, cls)
-class SlotDataSet(CuminSqlDataSet):
- def __init__(self, app):
- super(SlotDataSet, self).__init__(app)
-
- self.where_exprs.default = list()
-
- def sort_records(self, records):
- try:
- for rec in records:
- rec["category"], rec["category_group"] = SlotMapPage.get_cat_and_group(rec["State"], rec["Activity"])
- recs = sorted(records, key=lambda x:"%s%s%s" %
- (x["category_group"], x["category"], x["Name"]))
- except Exception:
- return records
- return recs
-
class SlotLoadStatSet(StatSet):
def __init__(self, app, name, object):
super(SlotLoadStatSet, self).__init__(app, name, object)
@@ -81,497 +65,3 @@
return [(x.get_title(session), x.value(session, obj), x.escape)
for x in cls.properties if x.category == self.category]
-class SlotMapPage(Page):
- """ handles the slots.vis request """
-
- categories = {("Owner", None): ("Unavailable", "Owner"),
- ("Unclaimed", None): ("Available", "Unclaimed"),
- ("Matched", None): ("Starting", "Transitioning"),
- ("Claimed", "Idle"): ("Starting", "Transitioning"),
- ("Claimed", "Busy"): ("Running", "Busy"),
- ("Claimed", "Retiring"): ("Running", "Busy"),
- ("Claimed", "Suspended"): ("Paused", "Busy"),
- ("Preempting", None): ("Stopping", "Transitioning"),
- ("Unknown", None): ("Unknown", "Unknown")}
-
- shapes = {"Unavailable": {"shape": "filled_triangle", "color": (.6,.6,.6)},
- "Available": {"shape": "box", "color": (.6,.6,.6)},
- "Stopping": {"shape": "diagonal", "color": (1,.2,.2)},
- "Starting": {"shape": "diagonal", "color": (.2,1,8)},
- "Paused": {"shape": "solid", "color": (1,.2,.2)},
- "Running": {"shape": "solid", "color": (0,.8,0)},
- "Busy": {"shape": "solid", "color": (0,.8,0)},
- "Transitioning": {"shape": "diagonal", "color": (.8,0,.8)},
- "Unclaimed": {"shape": "box", "color": (.6,.6,.6)},
- "Owner": {"shape": "filled_triangle", "color": (.6,.6,.6)},
- "Unknown": {"shape": "solid", "color": (1,0,0)}}
-
- interiors = {"Idle": (.7,.7,.7),
- "Busy": (0.0, 0.4, 0.0),
- "Suspended": (1,0,0),
- "Vacating": (1,.73,.367),
- "Killing": (0,0,1),
- "Benchmarking": (1,.8,.8),
- "Retiring": (.8,.2,.8),
- "Unknown": (.8,.8,.8)}
-
- max_width = 400
- max_png_age = 30
-
- # start creating artificial groupings after the number of real groups
- max_top_level_items = 500
-
- def __init__(self, app, name, param=None, desc=""):
- super(SlotMapPage, self).__init__(app, name)
-
- self.object_param = param
- self.object_description = desc
-
- self.zoom_level = IntegerParameter(app, "zl")
- self.zoom_level.default = 1
- self.add_parameter(self.zoom_level)
-
- self.category = Parameter(app, "category")
- self.add_parameter(self.category)
-
- self.json = Parameter(app, "json")
- self.add_parameter(self.json)
-
- self.sequence = IntegerParameter(app, "seq")
- self.sequence.default = 0
- self.add_parameter(self.sequence)
-
- self.expanded = Parameter(app, "expanded")
- self.expanded.default = ""
- self.expanded.all = "all"
- self.add_parameter(self.expanded)
-
- self.group = Parameter(app, "group")
- self.add_parameter(self.group)
-
- self.slots = SlotDataSet(app)
-
- @classmethod
- def get_categories(cls):
- return cls.categories
-
- @classmethod
- def get_unique_category_groups(cls):
- categories = cls.categories
- d = dict()
- for x in categories:
- _, group = categories[x]
- if not group == "Unknown":
- d[group] = None
- return d.keys()
-
- def get_content_type(self, session):
- return self.json.get(session) and "text/plain" or "image/png"
-
- def get_cache_control(self, session):
- return "no-cache"
-
- def render_category(self, session, category):
- map = HeatMapChart()
- surface = map.plot_colored_shape(self.shapes[category]["color"],
- self.shapes[category]["shape"], 20, 20)
- writer = Writer()
- surface.write_to_png(writer)
- return writer.to_string()
-
- def do_render(self, session):
- # render the legend icon
- category = self.category.get(session)
- if category:
- return self.render_category(session, category)
-
- # generate the json data for the flash chart
- if self.json.get(session):
- return self.render_json(session)
-
- zl = self.zoom_level.get(session)
-
- map = HeatMapChart(self.max_width, self.max_width)
-
- cursor = self.slots.execute(session)
- records = cursor_to_rows(cursor)
-
- if len(records) == 0:
- return
-
- records = self.slots.sort_records(records)
- shape_info = list()
- for rec in records:
- cat = rec["category"]
- shape_info.append(self.shapes[cat])
- size = map.plot_shapes(shape_info, zl)
-
- args = (size, map.width, map.height, len(shape_info), map.rows, map.cols)
- cookie = "|".join((str(x) for x in args))
- session.set_cookie("slot_info", cookie)
-
- writer = Writer()
- map.write(writer)
- return writer.to_string()
-
- def split_compound_attribute(self, record, attr):
- if "|" in attr:
- attr_list = attr.split("|")
- atr_list = [record[x] for x in attr_list]
- return ":".join(atr_list)
- return ""
-
- def get_info_array(self, records, array, attr):
- '''
- Creates a list of record indexes for each unique value of attr
- @param records: all the records
- @param array: list of indexes to check
- @param attr: the rosemary attribute to create the array for
- '''
- d = dict()
- for i in array:
- try:
- atr = records[i][attr]
- except KeyError:
- atr = self.split_compound_attribute(records[i], attr)
- if not atr:
- atr = "Unknown %s" % attr
- if not atr in d:
- d[atr] = {"plist": list()}
- d[atr]["klist"] = [atr]
- d[atr]["plist"].append(i)
- return d
-
- def collapse_level(self, level_dict, count):
- collapsed = dict()
-
- def save_bucket(low_key, key, plist, keylist):
- if low_key is not key:
- coll_key = "%s - %s" % (low_key, key)
- else:
- coll_key = low_key
- collapsed[coll_key] = {"plist": plist,
- "klist": keylist}
-
- plist = list()
- keylist = list()
- max_edge = len(level_dict) - 1
- bucket_size = int(max_edge / count)
- edge = bucket_size
- low_key = None
- for i, key in enumerate(sorted(level_dict.keys())):
- if not low_key:
- low_key = key
- plist.extend(level_dict[key]["plist"])
- keylist.append(key)
- if i >= edge:
- save_bucket(low_key, key, plist, keylist)
- low_key = None
- plist = list()
- keylist = list()
- edge += bucket_size
- if edge > max_edge:
- edge = max_edge
-
- if low_key:
- save_bucket(low_key, key, plist, keylist)
- return collapsed
-
- @classmethod
- def get_cat_and_group(cls, state, activity):
- act = activity
- if state in ("Owner", "Unclaimed", "Matched", "Preempting", "Unknown"):
- # activity doesn't matter for these states
- act = None
- try:
- cat, cat_group = cls.categories[(state, act)]
- except:
- log.debug("Problem finding state and activity", exc_info=True)
- cat, cat_group = ("%s:%s" % (state, activity), "Unknown")
-
- return cat, cat_group
-
- def get_cats(self, records, plist):
- d = dict()
- for i in plist:
- state = records[i]["State"]
- activity = records[i]["Activity"]
-
- cat, cat_group = SlotMapPage.get_cat_and_group(state, activity)
- if not cat_group in d:
- d[cat_group] = dict()
- if not cat in d[cat_group]:
- d[cat_group][cat] = 0
- d[cat_group]["_count"] = 0
- d[cat_group]["_count"] += 1
- d[cat_group][cat] += 1
-
- return d
-
- def render_json(self, session):
- cursor = self.slots.execute(session)
- records = cursor_to_rows(cursor)
-
- if len(records) == 0:
- return "[]"
-
- records = self.slots.sort_records(records)
- group = self.group.get(session)
- slot_count = len(records)
-
- root = Element()
-
- # Not sure these are used. Code was modified
- # when collector filtering was removed. If values
- # are needed here they can be synthesized in the case
- # of a collector
- root.name = self.object_description
- if self.object_param != None:
- root.value = self.object_param.get(session)._id
- else:
- root.value = ""
-
- root.slots = slot_count
- json = self.json.get(session)
- sequence = self.sequence.get(session)
- root.vis = json
- root.seq = sequence
- root.shape_info = self.shapes
- root.activity_colors = self.interiors
- expanded = self.expanded.get(session)
- root.tree = self.treeify(records, range(slot_count), group, expanded)
- root.back = False
- return "[%s]" % root.create()
-
- def treeify(self, records, plist, group, expanded):
- def add_branch(level_list, tree, back, group, key, slots):
- if len(tree):
- el = Element()
- el.tree = tree
- el.back = back
- el.name = group
- el.value = key
- el.slots = slots
- el.level = 0
- level_list.append(el)
-
- def gen_leaves(plist):
- level_list = list()
- for i in sorted(plist, key=lambda x:"%s%s%s" %
- (records[x]["category_group"], records[x]["category"], records[x]["Name"])):
- el = Element()
- el.job_id = records[i]["JobId"] and records[i]["JobId"] or ""
- el.activity = records[i]["Activity"] and records[i]["Activity"] or "Unknown"
- el.state = records[i]["State"] and records[i]["State"] or "Unknown"
- el.category = records[i]["category"]
- el.category_group = records[i]["category_group"]
- el.value = records[i]["Name"] and records[i]["Name"] or ""
- el.load_avg = records[i]["LoadAvg"] and round(records[i]["LoadAvg"], 2) or 0
- el.name = "slot"
- el.slot_id = records[i]["_id"]
- level_list.append(el)
- return level_list
-
- def gen_summary(plist):
- # display summary info for all the slots under this grouping
- level_list = list()
- category_groups = self.get_cats(records, plist)
- for category_group in sorted(category_groups):
- el = Element()
- el.name = "slot_info"
- el.category = category_group
- el.category_group = category_group
- el.count = category_groups[category_group]["_count"]
- try:
- el.value = "%s.%s" % (records[plist[0]][group], category_group) # uid
- except KeyError:
- atr = self.split_compound_attribute(records[plist[0]], group)
- el.value = "%s.%s" % (atr, category_group)
- level_list.append(el)
- return level_list
-
- level_list = list()
- if not group:
- tree = gen_leaves(plist)
- add_branch(level_list, tree, False, "", "", len(plist))
- return level_list
-
- original_level_dict = level_dict = self.get_info_array(records, plist, group)
-
- if len(original_level_dict) > self.max_top_level_items:
- # collapse groups into artificial sub-groups
- level_dict = self.collapse_level(original_level_dict, self.max_top_level_items)
-
- for key in sorted(level_dict):
- tree = list()
- if not expanded:
- #if len(level_dict) == 1:
- # # there is only one grouping. no need to make them click on it
- # tree = gen_leaves(level_dict[key]["plist"])
- # add_branch(level_list, tree, False, group, key, len(level_dict[key]["plist"]))
- #else:
- # display the top level of groups (artificial or natural)
- tree = gen_summary(level_dict[key]["plist"])
- add_branch(level_list, tree, False, group, key, len(level_dict[key]["plist"]))
- elif expanded == key:
- # lowest level of a natural group
- if key in original_level_dict:
- tree = gen_leaves(level_dict[key]["plist"])
- add_branch(level_list, tree, True, group, key, len(level_dict[key]["plist"]))
- else:
- # we want to display the groups that went into an atrificial sub-group
- for original_key in level_dict[key]["klist"]:
- tree = gen_summary(original_level_dict[original_key]["plist"])
- add_branch(level_list, tree, True, group, original_key, len(original_level_dict[original_key]["plist"]))
- elif expanded in level_dict[key]["klist"]:
- # lowest level of an artificial group
- tree = gen_leaves(original_level_dict[expanded]["plist"])
- add_branch(level_list, tree, True, group, expanded, len(original_level_dict[expanded]["plist"]))
-
- return level_list
-
-class SlotMap(Widget):
- def __init__(self, app, name):
- super(SlotMap, self).__init__(app, name)
-
- self.slots = SlotDataSet(app)
-
- self.slot_info = self.SlotInfo(app, "slot_info", self.slots)
- self.add_child(self.slot_info)
-
- self.slot_legend = self.SlotLegend(app, "slot_legend")
- self.add_child(self.slot_legend)
-
- self.slot_clip_size = 400
-
- def render_image_href(self, session):
- raise Exception("Not implemented")
-
- def render_job_index_param(self, session):
- return "xargs"
-
- def render_fullpageable(self, session):
- return "fullpageable"
-
- def render_slot_url(self, session):
- slot = Identifiable("XXX")
- try:
- return self.page.main.grid.slot.get_href(session, slot)
- except:
- pass
-
- def render_slot_clip_size(self, session):
- return self.slot_clip_size
-
- class SlotLegend(ItemSet):
- def __init__(self, app, name):
- super(SlotMap.SlotLegend, self).__init__(app, name)
-
- categories = SlotMapPage.get_unique_category_groups()
- for cat in sorted(categories):
- acat = SlotCategories(app, cat)
- self.add_child(acat)
-
- def do_get_items(self, session):
- return self.children
-
- def render_category(self, session, cat):
- return cat.name
-
- def render_category_items(self, session, cat):
- return cat.render(session)
-
- class SlotInfo(ItemSet):
- display_names = {"category": ("", "", ""),
- "JobId": ("Job ID", "", ""),
- "System": ("System", "", ""),
- "Machine": ("Machine", "", ""),
- "State": ("State", "", ""),
- "Activity": ("Activity", "", ""),
- "Name": ("Name", "", ""),
- "_id": ("Slot_ID", "slotInfo_id", "hidden_row")}
-
- def __init__(self, app, name, slot_data):
- super(SlotMap.SlotInfo, self).__init__(app, name)
-
- self.index = IntegerParameter(app, "i")
- self.add_parameter(self.index)
-
- self.slot = Attribute(app, "slot")
- self.add_attribute(self.slot)
-
- self.slot_data = slot_data
-
- self.info_div_tmpl = WidgetTemplate(self, "bg_html")
-
- def do_render(self, session):
- index = self.index.get(session)
-
- if index is not None:
- #self.parent.slots.limit.set(session, 1)
- #self.parent.slots.offset.set(session, index)
-
- cursor = self.slot_data.execute(session)
- records = cursor_to_rows(cursor)
-
- if len(records):
- records = self.slot_data.sort_records(records)
-
- self.slot.set(session, records[index])
-
- writer = Writer()
- self.info_div_tmpl.render(writer, session)
- return writer.to_string()
- else:
- return super(SlotMap.SlotInfo, self).do_render(session)
-
- def do_get_items(self, session):
- slot = self.slot.get(session)
-
- return ((
- x == "category" and (slot["category_group"],"","title_row") or self.display_names[x],
- slot[x])
- for x in slot if x in self.display_names)
-
- def render_slot_info_url(self, session):
- return self.page.get_update_url(session, (self,))
-
- def render_slot_info_index(self, session):
- return self.index.path
-
- def render_item_value(self, session, item):
- return item[1]
-
- def render_item_title(self, session, item):
- return item[0][0]
-
- def render_item_id(self, session, item):
- return item[0][1] and "id='%s'" % item[0][1] or ""
-
- def render_item_row_class(self, session, item):
- return item[0][2] and "class='%s'" % item[0][2] or ""
-
-class SlotCategories(ItemSet):
- def do_get_items(self, session):
- cat_group = self.name
- categories = SlotMapPage.get_categories()
-
- d = dict()
- for x in categories:
- cat, group = categories[x]
- if group is cat_group:
- d[cat] = None
-
- return sorted(d.keys())
-
- def render_item_size(self, session, cat):
- return 20
-
- def render_item_title(self, session, cat):
- return cat
-
- def render_item_href(self, session, cat):
- params = list()
- params.append("category=%s" % cat)
-
- return "resource?name=slotvis-" + cat + ".png"
Modified: trunk/cumin/python/cumin/grid/slot.strings
===================================================================
--- trunk/cumin/python/cumin/grid/slot.strings 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/grid/slot.strings 2012-03-21 20:09:23 UTC (rev 5260)
@@ -39,389 +39,3 @@
</tbody>
</table>
-[SlotMap.javascript]
-addJavascript('resource?name=slotvis.js', 'head');
-
-[SlotMap.css]
-div#slot_hover {
- visibility: hidden;
- position: absolute;
- border: 1px solid pink;
- left: 0;
- top: 0;
- z-index: 10;
- width: 28px;
- height: 28px;
-/* -moz-border-radius: 50%; */
-}
-
-div#slot_zooming {
- margin: 3em auto;
- padding: 1em;
- z-index:200;
- text-align: center;
- background-color: white;
- overflow: hidden;
- opacity: 0.5;
- display: none;
- border: 1px solid #000;
-}
-
-div#slot_zooming p {
- margin: 0;
-/* padding: 140px 0 0 0; */
-}
-
-div#slot_controls {
- font-size: 0.8em;
- float: left;
- position: relative;
- left: 0px;
- top: 11px;
- z-index: 1;
-}
-
-div#slot_panleft {
- float: left;
- background: url(resource?name=pan-left.png) scroll no-repeat center;
- width: 18px;
- height: 0px;
-}
-
-div#slot_panright {
- float: left;
- background: url(resource?name=pan-right.png) scroll no-repeat center;
- width: 18px;
- height: 0px;
-}
-
-div#slot_panup {
- clear: both;
- background: url(resource?name=pan-up.png) scroll no-repeat center;
- height: 18px;
- width: 0px;
- position: relative;
- left: 18px;
- z-index:0;
-}
-
-div#slot_pandown {
- clear: left;
- background: url(resource?name=pan-down.png) scroll no-repeat center;
- height: 18px;
- width: 0px;
- position: relative;
- left: 18px;
-}
-
-div.slot_map {
- background-color: white;
- border: 1px solid #CCCCCC;
- float: left;
- height: 0px;
- overflow: hidden;
- position:relative;
- width: 0px;
-}
-
-div#slot_png {
- clip: rect(0 400px 400px 0);
- position:absolute;
- z-index: 0;
-}
-
-div#slot_glass {
- height: 0px;
- left: 0px;
- position:absolute;
- top: 0px;
- width: 0px;
- z-index: 100;
-}
-
-div#slot_visualization {
- position: relative;
- display: none;
- float: left;
-}
-
-div.zoom_node {
- background-color: white;
- position: absolute;
- left: -4px;
- top: -8px;
- color: #0066CC;
-}
-
-div.zoom_node_last {
- background-color: white;
- position: absolute;
- left: 2px;
- top: -8px;
- color: #0066CC;
-}
-
-div.zoom_first {
- width: 6px;
- height: 15px;
- border-bottom: 1px solid black;
- border-left: 1px solid black;
- float: left;
- position: relative;
- margin-left: 0.5em;
- cursor: pointer;
-}
-
-div.zoom_last {
- width: 6px;
- height: 15px;
- border-bottom: 1px solid black;
- border-right: 1px solid black;
- float: left;
- position: relative;
- margin-right: 0.5em;
- cursor: pointer;
-}
-
-div.zoom_middle_right {
- width: 6px;
- height: 15px;
- border-bottom: 1px solid black;
- border-left: 1px solid black;
- float: left;
- position: relative;
- cursor: pointer;
-}
-
-div.zoom_middle_left {
- width: 6px;
- height: 15px;
- border-bottom: 1px solid black;
- float: left;
- cursor: pointer;
-}
-
-div#zoom_text {
- margin-right: 1em;
- float:left;
-}
-
-div#zoom_levels {
- position:relative;
- float: left;
-}
-
-div#zoom_pos {
- background: url(slots.png?dot=Busy) scroll no-repeat center;
- width: 12px;
- height: 12px;
- position: absolute;
- top: 10px;
- z-index: 4;
-}
-
-[SlotMap.html]
-<div id="slot_visualization" class="fullpageable">
- <h2>Slots</h2>
- <div id="slot_controls">
- <div id="zoom_text">Zoom</div><div id="zoom_levels"><div id="zoom_pos"></div></div><div style="clear:left;"><!-- --></div>
- </div>
-
- <div id="slot_panup" onclick="vis.pan_up()"></div>
- <div id="slot_panleft" onclick="vis.pan_left()"></div>
- <div class="slot_map" id="{id}">
- <div id="slot_glass"><!-- mouse target to prevent selecting/dragging image --></div>
- <div id="slot_png">
- <img name="{id}" border="0" onload="vis.img_loaded(this)" onerror="vis.img_error(this)" alt="slots"/>
- </div>
- <div id="slot_hover"><!-- red border around current slot --></div>
- <div id="slot_zooming"><p>Zooming...</p></div>
- </div>
- <div id="slot_panright" onclick="vis.pan_right()"><!-- --></div>
- <div id="slot_pandown" onclick="vis.pan_down()"></div>
- {slot_legend}
-</div>
-<div style="clear: left"><!-- --></div>
-{slot_info}
-<script type="text/javascript">
-//<![CDATA[
- var show_slot_url = "{slot_url}";
- var flashversion = swfobject.getFlashPlayerVersion();
- if (flashversion.major < 9) {
- var psm = document.getElementById('pngSlotMap');
- if (psm)
- psm.style.display = "block";
- var theImage = document.images['{id}'];
- if (theImage) {
- theImage.src = "{image_href}";
- }
- var slot_current_id = "{id}";
- var slot_job_index = "{job_index_param}";
- var slot_map_info = {size: 0, width: 0, height: 0, count: 0, rows: 0, cols: 0};
- var slot_clip_size = {slot_clip_size};
- var original_clip_size = slot_clip_size;
- $('slot_visualization').onfullpage = function (width) { vis.notify(true, width); };
- $('slot_visualization').onrestore = function () { vis.notify(false, original_clip_size); };
- var oGlass = document.getElementById("slot_glass");
- if (oGlass) {
- oGlass.onmousedown = vis.downGlass;
- oGlass.onmouseup = vis.upGlass;
- oGlass.onmousemove = vis.moveGlass;
- oGlass.onmouseout = vis.outGlass;
- oGlass.ondblclick = clicks.doMouseDown;
- oGlass.onclick = clicks.doMouseDown;
- oGlass.dragging = false;
- oGlass.down_pos = null;
- }
- }
-//]]>
-</script>
-
-[SlotInfo.css]
-div.slot_info {
- position: absolute;
- top: 0;
- left: 0.5em;
- visibility: hidden;
- z-index: 301;
-}
-
-div.slot_container {
- position: absolute;
- background-color: #ffffaa;
- background-image: url(resource?name=shade.png);
- background-position: bottom left;
- background-repeat: repeat-x;
- border: 1px solid #cccc99;
- padding: 1em;
- z-index: 101;
-}
-
-td.slot_info_title {
- font-weight: bold;
- height: 1.1em;
- text-align: right;
- padding-right: 1em;
-}
-td.slot_info_value {
- font-weight: normal;
- height: 1.1em;
-}
-
-tr.title_row td.slot_info_title, tr.title_row td.slot_info_value {
- padding-bottom: 0.5em;
- border-bottom: 1px solid black;
- font-style: italic;
- font-weight: bold;
-}
-
-html > body .outerpair1 {
- background: url(resource?name=upperrightfade.png) right top no-repeat;
-}
-
-html > body .outerpair2 {
- background: url(resource?name=lowerleftfade.png) left bottom no-repeat;
- padding-top: 8px;
- padding-left: 8px;
-}
-
-html > body .shadowbox {
- background: url(resource?name=shadow.png) bottom right;
-}
-
-html > body .innerbox {
- position: relative;
- left: -8px;
- top: -8px;
-}
-
-tr.hidden_row {
- display: none;
-}
-
-[SlotInfo.html]
-<div id="{id}"><!-- place holder to receive backgound update of slot info on mouseover of a slot --></div>
-<script type="text/javascript">
- var slot_info_url = "{slot_info_url}";
- var slot_info_index = "{slot_info_index}";
- var slot_info_id = "{id}";
-</script>
-
-[SlotInfo.bg_html]
-<div class="outerpair1 slot_info" id="{id}">
- <div class="outerpair2">
- <div class="shadowbox">
- <div class="innerbox slot_container">
- <table cellspacing="0" cellpadding="0" border="0">{items}</table>
- </div>
- </div>
- </div>
-</div>
-
-[SlotInfo.item_html]
-<tr {item_row_class}>
- <td class="slot_info_title">{item_title}</td>
- <td {item_id} class="slot_info_value">{item_value}</td>
-</tr>
-
-[SlotLegend.css]
-div.SlotLegend div.slot_container {
- background-image: url(resource?name=shade1.png);
-}
-div.SlotLegend {
- margin: 0 0 0 2em;
- width: 12em;
-}
-div.SlotLegend dl {
- margin: auto;
- padding: 0;
- position: relative;
- top: -0.5em;
-}
-div.SlotLegend dt {
- margin: 0;
- padding: 1em 0 0 0;
- font-weight: bold;
-}
-div.SlotLegend dd {
- margin: 0 0 0 1em;
- padding: 0;
- cursor: default;
-}
-div.SlotLegend dd:hover {
- color: #FF0000;
-}
-div.SlotLegend dd img {
- margin: 0;
- position: relative;
- top: 6px;
-}
-
-[SlotLegend.html]
-<div id="{id}" class="{class}">
- <div class="outerpair1" id="{id}">
- <div class="outerpair2">
- <div class="shadowbox">
- <div class="innerbox slot_container">
- <dl>
- {items}
- </dl>
- </div>
- </div>
- </div>
- </div>
-</div>
-
-[SlotLegend.item_html]
- <dt>{category}</dt>
- {category_items}
-
-[SlotCategories.html]
-{items}
-
-[SlotCategories.item_html]
-<dd onmouseover="vis_treemap_over('category', '{item_title}')" onmouseout="vis_treemap_out('category', '{item_title}')">
- <img src="{item_href}" width="{item_size}" height="{item_size}" title="{item_title}" alt="{item_title}"/>
-
- {item_title}
-</dd>
Modified: trunk/cumin/python/cumin/grid/slotvis.py
===================================================================
--- trunk/cumin/python/cumin/grid/slotvis.py 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/grid/slotvis.py 2012-03-21 20:09:23 UTC (rev 5260)
@@ -5,7 +5,6 @@
from wooly.util import StringCatalog
from wooly.widgets import RadioModeSet
-from slot import SlotMap, SlotMapPage
from cumin.parameters import RosemaryObjectParameter
from cumin.widgets import StateSwitch
from cumin.stat import FlashFullPage
@@ -51,89 +50,3 @@
def render_title(self, session):
return "Slot table"
-class Visualization(Widget):
- def __init__(self, app, name):
- super(Visualization, self).__init__(app, name)
-
- slot_map = PoolSlotMap(app, "slot_png")
- self.add_child(slot_map)
-
- slot_vis = PoolSlotFlashVis(app, "slot_map")
- self.add_child(slot_vis)
-
- def render_title(self, session):
- return "Slot visualization"
-
-class PoolSlotMap(SlotMap):
- def render_image_href(self, session):
- page = self.app.grid.pool_slots_page
- return Session(page).marshal()
-
-class PoolSlotFlashVis(PoolSlotMap):
- def __init__(self, app, name):
- super(PoolSlotFlashVis, self).__init__(app, name)
-
- self.group_by = self.GroupBySwitch(app, "group_by")
- self.add_child(self.group_by)
-
- self.fullpageable = True
-
- def render_slots_href(self, session):
- page = self.app.grid.pool_slots_page
- sess = Session(page)
- page.json.set(sess, "slots")
- page.group.set(sess, self.group_by.get(session))
-
- return sess.marshal()
-
- def render_image_href(self, session):
- page = self.app.grid.pool_slots_page
- return Session(page).marshal()
-
- def render_slot_chart_width(self, session):
- return 740
-
- def render_slot_chart_height(self, session):
- cursor = self.slots.execute(session)
- data = cursor.fetchall()
-
- slot_size = 51
- count = len(data)
- # individual slots are 51 px wide and tall
- width = self.render_slot_chart_width(session)
- cols = int(width / slot_size) * 4
- rows = int(math.ceil(count / cols))
-
- return min(max(rows * slot_size, width), 4095)
-
- def render_fullpageable(self, session):
- return self.fullpageable and "fullpageable" or ""
-
- def render_fullpage_href(self, session):
- page = self.app.grid.pool_slots_fullpage
- sess = Session(page)
- return sess.marshal()
-
- class GroupBySwitch(StateSwitch):
- def __init__(self, app, name):
- super(PoolSlotFlashVis.GroupBySwitch, self).__init__(app, name)
-
- self.add_state("Activity|State", "By activity/state")
- self.add_state("AccountingGroup", "By accounting group")
-
- 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)
-
-class PoolSlotFullPage(FlashFullPage):
- def __init__(self, app, name):
- super(PoolSlotFullPage, self).__init__(app, name)
-
- self.flash_chart = PoolSlotFlashVis(app, "chart")
- self.flash_chart.fullpageable = False
- self.replace_child(self.flash_chart)
-
- def render_content(self, session):
- return self.flash_chart.render(session)
-
Modified: trunk/cumin/python/cumin/grid/slotvis.strings
===================================================================
--- trunk/cumin/python/cumin/grid/slotvis.strings 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/grid/slotvis.strings 2012-03-21 20:09:23 UTC (rev 5260)
@@ -1,210 +1,3 @@
-[PoolSlotFlashVis.css]
-div#PoolSlotFlashVis {
- visibility: hidden;
-}
-
-div#PoolSlotFlashVis div.StatValueChart {
- width: auto;
-}
-
-div#PoolSlotFlashVis div.slot_legend {
- float: left;
-}
-div#PoolSlotFlashVis div.SlotLegend {
- margin: 4em 0 0 2em;
-}
-div#PoolSlotFlashVis div.slot_visualization {
- float: left;
-}
-
-div.SlotVisChart div.duration {
- margin: 1em 0 0.5em 1em;
- width:300px;
-}
-
-[PoolSlotFlashVis.html]
-<div id="PoolSlotFlashVis">
- <h2>Slots</h2>
- <div class="StatValueChart SlotVisChart {fullpageable}" id="{id}">
- <h2>{title}</h2>
- <div class="slot_visualization">
- <div class="duration">{group_by}</div>
- <div id="{id}_chart"></div>
- </div>
- <div class="slot_legend">{slot_legend}</div><div style="clear:both;"></div>
- </div>
-</div>
-<script type="text/javascript">
-//<![CDATA[
- // called every time the page is updated (currently 10 secs) and
- // when the user expands/collapses the flash chart
- function updatePoolSlotVis(id, loadType) {
- var chart = cumin.getFlashChart(id);
- if (typeof loadType == "undefined")
- loadType = "load";
- if ((chart != null) && (typeof chart.src != "undefined")) {
-
- var seq = incrementChartSequence(chart);
- if ((loadType == "reload") && (typeof chart.reload != "undefined")) {
- chart.reload(chart.src, seq);
- wooly.log("reloaded chart " + chart.src);
- }
- else if ((loadType == "load") && (typeof chart.load != "undefined")) {
- chart.load(chart.src, seq);
- wooly.log("loaded chart " + chart.src);
- }
- else {
- wooly.log("load not defined for " + id);
- }
- }
- }
-
- function vis_loaded(data) {
- if (data == "1") {
- $('PoolSlotFlashVis').style.visibility = "visible";
- }
- }
- function vis_ready(vis) {
- if (vis == "slots") {
- var chart = cumin.getFlashChart("{id}");
- chart.src = "{slots_href}";
- updatePoolSlotVis('{id}', "load");
- }
- }
-
- // we want to drill down a level in the slot vis
- function vis_expand(parent) {
- if (parent == null) {
- parent = "None";
- }
- var chart = cumin.getFlashChart("{id}");
- var src = chart.src;
- var branch = wooly.session.branch(src);
-
- // save the value of the current expanded
- var curExpand = "";
- if (typeof branch.expanded != "undefined") {
- curExpand = branch.expanded;
- }
-
- // expand to the level that was passed in
- branch['expanded'] = parent;
-
- // add the original expand to the end of the back list
- var backList = [];
- if (typeof branch.back != "undefined") {
- backList = branch.back.split("|");
- }
- if (curExpand != "")
- backList.push(curExpand);
- if (backList.length > 0)
- branch["back"] = backList.join("|");
- else if (typeof branch.back != "undefined")
- delete branch.back;
-
- chart.src = branch.marshal();
- updatePoolSlotVis("{id}", "load");
- var myFx = new Fx.Scroll(window).toTop();
- }
-
- // we want to go back 1 level in the slot vis
- function vis_back() {
- var chart = cumin.getFlashChart("{id}");
- var src = chart.src;
- var branch = wooly.session.branch(src);
-
- // get the current back list
- var backList = [];
- if (typeof branch.back != "undefined") {
- backList = branch.back.split("|");
- }
-
- // remove the last entry from the back list
- // and use it as the expand
- var expand = backList.pop();
- if (typeof expand != "undefined") {
- branch["expanded"] = expand;
- } else {
- // we are back to the top level
- if (typeof branch.expanded != "undefined")
- delete branch.expanded;
- }
-
- // save the new back list
- if (backList.length > 0) {
- branch["back"] = backList.join("|");
- } else {
- if (typeof branch.back != "undefined")
- delete branch.back;
- }
-
- chart.src = branch.marshal();
- updatePoolSlotVis("{id}", "load");
- }
-
- function vis_treemap_over(type, value) {
- var chart = cumin.getFlashChart("{id}");
- if (chart) {
- if (typeof chart.highlight != "undefined")
- chart.highlight(type, value);
- }
- }
- function vis_treemap_out(type, value) {
- var chart = cumin.getFlashChart("{id}");
- if (chart) {
- if (typeof chart.lowlight != "undefined")
- chart.lowlight(type, value);
- }
- }
- function slot_vis(state, a, id, href) {
- var li = a.parentNode;
- var ul = li.parentNode;
- var as = ul.getElementsByTagName('a');
- for (var i=0; i < as.length; i++) {
- as[i].className = (as[i] == a) ? "selected" : "";
- }
-
- var branch = wooly.session.branch(href);
- if (state == "None") {
- if ("group" in branch)
- delete branch.group;
- } else {
- branch.group = state;
- }
- var src = branch.marshal();
- var chart = cumin.getFlashChart(id);
- chart.src = src
- updatePoolSlotVis(id, "load");
- return false;
- }
-
- function init_flash() {
- var flashversion = swfobject.getFlashPlayerVersion();
- if (flashversion.major >= 9) {
- var fsm = document.getElementById('flashSlotMap');
- if (fsm)
- fsm.style.display = "block";
-
- var params = {menu: "false", scale: "noScale", allowFullscreen: "true", allowScriptAccess: "always", bgcolor: "#FFFFFF"};
- var branch = wooly.session.branch();
- if (branch.formBackground) {
- var i = 1;
- params.wmode = "opaque";
- }
-
- swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"}, params);
-
- wooly.addPageUpdateListener(function () { updatePoolSlotVis('{id}', "reload"); });
- window.addEvent('domready',function () {
- cumin.setFullpageHandler('{id}', '{fullpage_href}');
- });
- }
- }
- window.addEvent('domready', init_flash);
-
-//]]>
-</script>
-
[SlotSelector.css]
div.SlotSelector div.ObjectSelectorFilters {
padding-bottom: 0.5em;
Modified: trunk/cumin/python/cumin/inventory/main.py
===================================================================
--- trunk/cumin/python/cumin/inventory/main.py 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/inventory/main.py 2012-03-21 20:09:23 UTC (rev 5260)
@@ -21,9 +21,6 @@
self.app.main_page.main.inventory = self.frame
self.app.main_page.main.add_tab(self.frame)
- self.app.system_slots_page = SystemSlotMapPage(self.app, "systemslots.png")
- self.app.add_page(self.app.system_slots_page)
-
class InventoryFrame(CuminFrame):
def __init__(self, app, name):
super(InventoryFrame, self).__init__(app, name)
Modified: trunk/cumin/python/cumin/inventory/system.py
===================================================================
--- trunk/cumin/python/cumin/inventory/system.py 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/inventory/system.py 2012-03-21 20:09:23 UTC (rev 5260)
@@ -1,5 +1,4 @@
from operator import itemgetter
-from cumin.grid.slot import SlotMap, SlotMapPage
from cumin.objectselector import ObjectSelector, ObjectLinkColumn, ObjectTable, ObjectTableColumn
from cumin.objectframe import ObjectFrame
@@ -123,10 +122,7 @@
chart = StatFlashChart(app, "loadavg", system)
chart.stats = ("loadAverage1Min",)
self.add_child(chart)
-
- slots = SystemSlotMap(app, "system_slot_map", system)
- self.add_child(slots)
-
+
self.main_tmpl = WidgetTemplate(self, "html")
def render_title(self, session):
@@ -223,67 +219,6 @@
def render_title(self, session):
return "Configuration"
-class SystemSlotMap(SlotMap):
- def __init__(self, app, name, system):
- super(SystemSlotMap, self).__init__(app, name)
-
- self.system = system
- self.slot_clip_size = 280
-
- def do_process(self, session):
- super(SystemSlotMap, self).do_process(session)
-
- system = self.system.get(session)
- self.slots.add_where_expr(session, "\"System\" = '%s'", system.nodeName)
-
- def render_image_href(self, session):
- system = self.system.get(session)
-
- page = self.app.system_slots_page
- sess = Session(page)
-
- #page.sysimage.set(sess, system._id)
- page.sysimage.set(sess, system)
-
- return sess.marshal()
-
- def render_slot_url(self, session):
- return ""
-
-class SystemSlotFlashVis(SystemSlotMap):
- def render_slots_href(self, session):
- system = self.system.get(session)
-
- page = self.app.system_slots_page
- sess = Session(page)
-
- page.sysimage.set(sess, system)
- page.json.set(sess, "slots")
- page.group.set(sess, None)
-
- return sess.marshal()
-
- def render_slot_chart_width(self, session):
- return 250
-
- def render_slot_chart_height(self, session):
- return 250
-
-class SystemSlotMapPage(SlotMapPage):
- def __init__(self, app, name):
- self.cls = app.model.com_redhat_sesame.Sysimage
- self.sysimage = RosemaryObjectParameter(app, "id", self.cls)
-
- super(SystemSlotMapPage, self).__init__(app, name, self.sysimage, "System")
-
- self.add_parameter(self.sysimage)
-
- def do_process(self, session):
- super(SystemSlotMapPage, self).do_process(session)
-
- sysimage = self.sysimage.get(session)
- self.slots.add_where_expr(session, "\"System\" = '%s'", sysimage.nodeName)
-
class WallabyAndSqlAdapter(ObjectSqlAdapter):
def get_count(self, values):
Modified: trunk/cumin/python/cumin/inventory/system.strings
===================================================================
--- trunk/cumin/python/cumin/inventory/system.strings 2012-03-21 15:25:05 UTC (rev 5259)
+++ trunk/cumin/python/cumin/inventory/system.strings 2012-03-21 20:09:23 UTC (rev 5260)
@@ -42,76 +42,6 @@
[SystemServices.item_html]
<tr><th>{item_type}</th><td>{item_content}</td></tr>
-[SystemSlotFlashVis.css]
-div#SystemSlotFlashVis {
- visibility: hidden;
-}
-
-.system_slot_legend {
- float: right;
- width: 150px;
-}
-
-.system_slot_vis {
- float: left;
- width: 250px;
-}
-
-[SystemSlotFlashVis.html]
-<div id="SystemSlotFlashVis">
- <h2>Slots</h2>
- <div class="StatValueChart SlotVisChart {fullpageable}" id="{id}">
- <h2>{title}</h2>
- <div class="slot_visualization">
- <div class="system_slot_vis" id="{id}_chart"></div>
- <div class="slot_legend system_slot_legend">{slot_legend}</div>
- </div>
- <div style="clear:both;"></div>
- </div>
-</div>
-<script type="text/javascript">
-//<![CDATA[
- function updateSystemSlotVis(id, loadType) {
- var chart = cumin.getFlashChart(id);
- if ((chart != null) && (typeof chart.src != "undefined")) {
- var seq = incrementChartSequence(chart);
- if (typeof loadType != "undefined") {
- if (typeof chart.reload != "undefined")
- chart.reload(chart.src, seq);
- } else {
- if (typeof chart.load != "undefined")
- chart.load(chart.src, seq);
- else
- wooly.log("load not defined for " + id);
- }
- }
- }
- function vis_loaded(data) {
- if (data == "1") {
- $('SystemSlotFlashVis').style.visibility = "visible";
- }
- }
- function vis_ready(vis) {
- if (vis == "slots") {
- var chart = cumin.getFlashChart("{id}");
- chart.src = "{slots_href}";
- updateSystemSlotVis('{id}');
- }
- }
- var flashversion = swfobject.getFlashPlayerVersion();
- if (flashversion.major >= 9) {
- var fsm = document.getElementById('flashSlotMap');
- if (fsm)
- fsm.style.display = "block";
-
- var params = {menu: "false", scale: "noScale", allowFullscreen: "true", allowScriptAccess: "always", bgcolor: "#FFFFFF"};
- swfobject.embedSWF("resource?name=slots.swf", "{id}_chart", "{slot_chart_width}", "{slot_chart_height}", "9.0.0", "", {vis:"slots"}, params);
-
- wooly.addPageUpdateListener(function () { updateSystemSlotVis('{id}', "reload"); });
- }
-//]]>
-</script>
-
[SystemTagSet.html]
<table id="{id}" class="{class} PropertySet TagPropertySet">
<thead>
12 years, 1 month
r5259 - in branches/roles: cumin/bin cumin/instance/etc cumin/metadata cumin/metadata/access cumin/python/cumin wooly/python/wooly
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-03-21 15:25:05 +0000 (Wed, 21 Mar 2012)
New Revision: 5259
Added:
branches/roles/cumin/metadata/access/
branches/roles/cumin/metadata/access/usergrid.xml
branches/roles/cumin/python/cumin/authorize.py
Modified:
branches/roles/cumin/bin/cumin-admin
branches/roles/cumin/bin/cumin-web
branches/roles/cumin/instance/etc/cumin.conf
branches/roles/cumin/python/cumin/config.py
branches/roles/cumin/python/cumin/main.py
branches/roles/cumin/python/cumin/widgets.py
branches/roles/wooly/python/wooly/__init__.py
Log:
Initial role enforcement sources.
Modified: branches/roles/cumin/bin/cumin-admin
===================================================================
--- branches/roles/cumin/bin/cumin-admin 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/bin/cumin-admin 2012-03-21 15:25:05 UTC (rev 5259)
@@ -542,7 +542,7 @@
def handle_remove_assignment(app, cursor, opts, args):
user, role = get_user_and_role(app, cursor, args)
-
+ #TODO: check if user exists otherwise exc occures
assignment = app.admin.get_assignment(cursor, user, role)
if not assignment:
Modified: branches/roles/cumin/bin/cumin-web
===================================================================
--- branches/roles/cumin/bin/cumin-web 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/bin/cumin-web 2012-03-21 15:25:05 UTC (rev 5259)
@@ -138,6 +138,9 @@
set_aviary_configs(cumin, values)
set_wallaby_configs(cumin, values, broker_uris)
+ cumin.auth_create_ondemand = values.auth_create_ondemand
+ cumin.auth_proxy = values.auth_proxy
+
cumin.debug = opts.debug
cumin.user = values.user
cumin.update_interval = values.update_interval
Modified: branches/roles/cumin/instance/etc/cumin.conf
===================================================================
--- branches/roles/cumin/instance/etc/cumin.conf 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/instance/etc/cumin.conf 2012-03-21 15:25:05 UTC (rev 5259)
@@ -1,11 +1,17 @@
[common]
-# database: dbname=cumin user=cumin host=localhost
-# brokers: localhost:5672
-# debug: False
+database: dbname=cumin user=cumin host=localhost
+#database: dbname=cumin user=cumin host=172.22.88.13 port=5432 password=cumin
+#brokers: cumin/rasca@172.22.88.13:5672
+debug: True
[web]
# host: localhost
-# host: 0.0.0.0
-user: guest
+host: 0.0.0.0
+#user: guest
+authorize: usergrid.xml
+authz-mech:
+persona: default
+auth-proxy: true
+auth-create-ondemand: true
[data]
Added: branches/roles/cumin/metadata/access/usergrid.xml
===================================================================
--- branches/roles/cumin/metadata/access/usergrid.xml (rev 0)
+++ branches/roles/cumin/metadata/access/usergrid.xml 2012-03-21 15:25:05 UTC (rev 5259)
@@ -0,0 +1,34 @@
+<AccessMap>
+<GroupAccess name="nogroup">
+ <WidgetAccess reg="cumin.account.widgets.LoginForm"/>
+ <WidgetAccess reg="cumin.account.widgets.LoginPage"/>
+ <WidgetAccess reg="cumin.account.widgets.Submit"/>
+</GroupAccess>
+ <GroupAccess name="user">
+ <SubGroupAccess name="nogroup"/>
+ <WidgetAccess reg="cumin.usergrid.*" />
+ <WidgetAccess reg="cumin.account.*" />
+ <WidgetAccess reg="cumin.task.*" />
+ <WidgetAccess reg="cumin.widgets.CuminPageLinks"/>
+ <WidgetAccess reg="cumin.widgets.CuminHeartBeat"/>
+ <WidgetAccess reg="cumin.objectselector.*"/>
+ <WidgetAccess reg="cumin.widgets.About*" />
+ <WidgetAccess reg="cumin.widgets.CuminFormPage" />
+ <WidgetAccess reg="cumin.grid.submission.*" />
+</GroupAccess>
+ <GroupAccess name="admin">
+ <WidgetAccess reg=".*"/>
+ </GroupAccess>
+ <GroupAccess name="genericadmin">
+ <SubGroupAccess name="user"/>
+ <WidgetAccess reg="cumin.main.Main*"/>
+ <WidgetAccess reg="cumin.main.Overview*"/>
+ <WidgetAccess reg="cumin.main.Top*"/>
+ <WidgetAccess reg="cumin.widgets.Top*"/>
+ </GroupAccess>
+ <GroupAccess name="messagingadmin">
+ <SubGroupAccess name="user"/>
+ <WidgetAccess reg="cumin.main.Main*"/>
+ <WidgetAccess reg="cumin.main.MessagingView"/>
+ </GroupAccess>
+</AccessMap>
Added: branches/roles/cumin/python/cumin/authorize.py
===================================================================
--- branches/roles/cumin/python/cumin/authorize.py (rev 0)
+++ branches/roles/cumin/python/cumin/authorize.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+import logging
+import os.path
+import re
+
+try:
+ import xml.etree.ElementTree as etree
+except ImportError:
+ import elementtree.ElementTree as etree
+
+log = logging.getLogger("cumin.authorize")
+
+class CuminAuthorizeMap(object):
+
+ def __init__(self):
+ log.info("Initializing %s", self.__class__.__name__)
+ regs = []
+ self.mapping = {}
+ self.filepath = None
+
+ def __repr__(self):
+ return ("%s %s" % ( self.__class__.__name__, self.filepath ))
+
+ def parse_accessfile(self, filepath):
+ #TODO: handle exceptions during parsing
+ acctree = etree.ElementTree().parse(filepath)
+ merges = {}
+ for gacc in acctree.getiterator('GroupAccess'):
+ gkey = gacc.attrib["name"]
+ self.mapping[gkey] = []
+ log.debug("Adding group element %s" , gkey)
+ for child in gacc.getchildren():
+ if child.tag == "WidgetAccess":
+ wa = child.attrib['reg']
+ self.mapping[gkey].append(re.compile(wa))
+ log.debug("Addig widget access %s for %s", wa, gkey)
+ elif child.tag == "SubGroupAccess":
+ merges[gkey] = child.attrib["name"]
+ else:
+ log.error("Illegal access tag %s in tree", child.tag)
+ #TODO: handle adding properly
+ for k in merges.iterkeys():
+ self.mapping[k].extend(self.mapping[merges[k]])
+
+ def lookup(self,group,widget):
+ try:
+ for w in self.mapping[group]:
+ if w.match(widget):
+ return True
+ except KeyError:
+ return False
+ return False
+
+class CuminAuthorizator(object):
+ def __init__(self, app):
+ self.app = app
+ log.info("Initializing %s", self)
+ self.accmap = CuminAuthorizeMap()
+ modules = app.modules
+ #TODO: this should be configurable
+ access_path = app.home + "/metadata/access"
+ log.debug("Access file path is %s", access_path)
+ if os.path.isdir(access_path):
+ for accfile in os.listdir(access_path):
+ if os.path.isfile(access_path + "/" + accfile):
+ self.accmap.parse_accessfile(access_path + "/" + accfile)
+ else:
+ log.error("Path for access files does not exist!")
+ log.info("NODULES %s", modules)
+
+ def authorize(self,web_session, widget_name):
+ try:
+ group = web_session.client_session.attributes['login_session'].group
+ except KeyError:
+ group = "nogroup"
+ pass
+
+ #TODO: bleee ugly ugly ... -> CuminGenericWidget ? .
+ # skip wooly widgets ....
+ if widget_name.startswith("wooly"):
+ return True
+ if type(group) == type([]):
+ for g in group:
+ if self.accmap.lookup(g,widget_name):
+ log.debug("Allowing %s authorization for %s ",
+ widget_name, group)
+ return True
+ else:
+ return self.accmap.lookup(group,widget_name)
+
+ log.debug("Denying %s authorization for %s ", widget_name, group)
+ return False
+
Modified: branches/roles/cumin/python/cumin/config.py
===================================================================
--- branches/roles/cumin/python/cumin/config.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/config.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -51,7 +51,7 @@
param = ConfigParameter(web, "persona", str)
param.default = "grid"
-
+
param = ConfigParameter(web, "fast-view-attributes", str)
param.default = "JobStatus,Cmd,Args,ExitStatus,JobStartDate,LastRemoteHost,LastJobStatus,Owner"
@@ -64,6 +64,19 @@
param = ConfigParameter(web, "force-html-doctype", bool)
param.default = False
+ param = ConfigParameter(web, "authorize", str)
+ param.default = None
+
+ param = ConfigParameter(web, "authz-provider", str)
+ param.default = "internal"
+
+ param = ConfigParameter(web, "auth-create-ondemand", bool)
+ param.default = False
+
+ param = ConfigParameter(web, "auth-proxy", bool)
+ param.default = False
+
+
def create_data_section(self, name, strict_section):
data = CuminConfigSection(self, name, strict_section)
data.log_file.default = os.path.join(self.home, "log", name + ".log")
Modified: branches/roles/cumin/python/cumin/main.py
===================================================================
--- branches/roles/cumin/python/cumin/main.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/main.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -21,6 +21,7 @@
from util import *
from widgets import *
from authenticator import *
+from authorize import *
from sage.catalog import Catalog
from sage.qmf.qmfoperations import QmfOperations
from sage.wallaby.wallabyoperations import WallabyOperations
@@ -39,6 +40,9 @@
self.home = home
self.authmech = authmech
+ self.aut_create_ondemand = False
+ self.aut_proxy = False
+
model_dir = os.path.join(self.home, "model")
self.model = CuminModel(self, model_dir)
@@ -56,6 +60,9 @@
self.modules = list()
self.modules_by_name = dict()
+ self.authorizator = CuminAuthorizator(self)
+ self.authorize_cb = self.authorizator.authorize
+
self.tasks = list()
self.user = None
@@ -78,6 +85,7 @@
self.personas["grid"] = self._init_grid_persona
self.personas["messaging"] = self._init_messaging_persona
self._page_links = list()
+ # we need the modules list to authorize
# self.model.sql_logging_enabled = True
@@ -168,6 +176,7 @@
def init(self, schema_version_check=True):
log.info("Initializing %s", self)
+
# Create RPC interfaces for QMF and aviary.
# These service have overlapping functionality,
# so they are wrapped in a sage.Catalog object
@@ -291,9 +300,8 @@
def __init__(self, app, name):
self.app = app
self.name = name
-
self.tasks = list()
-
+ log.debug("Init cumin module %s", name )
assert not hasattr(app, self.name), self.name
self.app.modules.append(self)
Modified: branches/roles/cumin/python/cumin/widgets.py
===================================================================
--- branches/roles/cumin/python/cumin/widgets.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/cumin/python/cumin/widgets.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -51,7 +51,9 @@
super(CuminMainView, self).do_process(session, *args)
+
def show_child(self, session, child):
+
super(CuminMainView, self).show_child(session, child)
frame = self.page.get_frame(session)
@@ -81,7 +83,7 @@
return branch.marshal()
else:
return super(CuminMainView, self).render_tab_href(session, tab)
-
+
def render_about_href(self, session):
page = self.app.about_page
lsess = Session(page)
@@ -90,10 +92,10 @@
class CuminPageLinks(ItemSet):
def __init__(self, app, name):
super(CuminPageLinks, self).__init__(app, name)
-
+ self.app = app
self.html_class = CuminPageLinks.__name__
- self.check_admin = self.CheckAdmin(app)
+# self.check_admin = self.CheckAdmin(app)
def do_get_items(self, session):
return self.app.page_links
@@ -101,17 +103,18 @@
def render_item_content(self, session, page):
href = Session(page).marshal()
title = page.render_title(session)
+ #TODO: generalize ??
+ if self.app.authorize_cb(session,page.my_name):
+ return fmt_link(href, title)
- return fmt_link(href, title)
-
def render_item_class(self, session, page):
if page is session.page:
return "selected"
else:
return "_"
- class CheckAdmin(CuminSqlDataSet):
- pass
+# class CheckAdmin(CuminSqlDataSet):
+# pass
class CuminFrame(Frame, ModeSet):
def __init__(self, app, name):
@@ -156,7 +159,6 @@
def render_href(self, session, *args):
branch = session.branch()
-
if hasattr(self, "view"):
self.view.show(branch)
@@ -1179,6 +1181,36 @@
self.app = app
self.user = user
+ self.group = []
+ conn = self.app.database.get_connection()
+ cursor = conn.cursor()
+ user_cls = app.model.com_redhat_cumin.User
+ role_cls = app.model.com_redhat_cumin.Role
+ mapping_cls = app.model.com_redhat_cumin.UserRoleMapping
+
+ query = SqlQuery(role_cls.sql_table)
+
+ SqlInnerJoin(query,
+ mapping_cls.sql_table,
+ mapping_cls.role.sql_column,
+ role_cls._id.sql_column)
+
+ SqlInnerJoin(query,
+ user_cls.sql_table,
+ user_cls._id.sql_column,
+ mapping_cls.user.sql_column)
+ #TODO: one column ?
+ cols = [ role_cls.name.sql_column ]
+
+ filt = SqlComparisonFilter(user_cls._id.sql_column,user._id,'=')
+ query.add_filter(filt)
+ sql = query.emit(cols)
+ log.debug("%s",sql)
+ cursor.execute(sql)
+
+ for gname in cursor.fetchall():
+ self.group.append(gname[0])
+
self.created = datetime.now()
self.notifications = list()
@@ -1307,18 +1339,30 @@
if login.created > when:
return True
- elif self.app.user:
- cls = self.app.model.com_redhat_cumin.User
- users = cls.get_selection(session.cursor, name=self.app.user)
+ elif self.app.auth_proxy or self.app.user:
+ username = self.app.user
+ # proxy user overrides app defined user
+ try:
+ username = session.request_environment['HTTP_REMOTE_USER']
+ except KeyError:
+ log.debug("Proxy auth enabled but no remote user set")
+ pass
+ if username:
+ cls = self.app.model.com_redhat_cumin.User
+ users = cls.get_selection(session.cursor, name=username)
- if not users:
- raise Exception("User '%s' not found" % self.app.user)
+ if not users and not self.app.auth_proxy:
+ raise Exception("User '%s' not found" % self.app.user)
+ else:
+ log.info("User %s not found in db", username )
+#TODO prehodit do authenticatora
+# ondemand -> authenticator.create_user
+# user -> authenticator.force_login
- login = LoginSession(self.app, users[0])
- session.client_session.attributes["login_session"] = login
+ login = LoginSession(self.app, users[0])
+ session.client_session.attributes["login_session"] = login
- return True
-
+ return True
return False
def redirect_on_exception(self, session):
@@ -1332,7 +1376,7 @@
session.add_notice(Notice("An object being displayed became unavailable"))
return "/index.html"
-
+
def render_error(self, session):
cls, value, traceback = sys.exc_info()
Modified: branches/roles/wooly/python/wooly/__init__.py
===================================================================
--- branches/roles/wooly/python/wooly/__init__.py 2012-03-21 15:19:43 UTC (rev 5258)
+++ branches/roles/wooly/python/wooly/__init__.py 2012-03-21 15:25:05 UTC (rev 5259)
@@ -125,6 +125,8 @@
self.__defer_tmpl = WidgetTemplate(self, "deferred_html")
self.nocontent_tmpl = WidgetTemplate(self, "nocontent")
+ self.my_name = self.__class__.__module__ + '.' + self.__class__.__name__
+
def init(self):
log.debug("Initializing %s" % self)
@@ -286,6 +288,11 @@
child.save_parameters(session, params)
def process(self, session, *args):
+ #TODO: cleanup
+ log.debug("WOOLY PROCESS: %s", self.my_name)
+ if not self.app.authorize_cb(session, self.my_name):
+ return
+
if self.update_enabled:
self.page.enable_update(session, self)
@@ -305,6 +312,10 @@
child.process(session)
def render(self, session, *args):
+ #TODO: cleanup
+ log.debug("WOOLY RENDER: %s", self.my_name)
+ if not self.app.authorize_cb(session, self.my_name):
+ return ""
if self.app.debug:
profile = self.page.profile.get(session)
12 years, 1 month
r5258 - branches
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-03-21 15:19:43 +0000 (Wed, 21 Mar 2012)
New Revision: 5258
Added:
branches/roles/
Log:
Create a branch for role enforcement development
12 years, 1 month
r5257 - tags
by tmckay@fedoraproject.org
Author: tmckay
Date: 2012-03-21 15:15:43 +0000 (Wed, 21 Mar 2012)
New Revision: 5257
Added:
tags/cumin-0.1.5192/
Log:
Create tag for 5192
12 years, 1 month
r5256 - in trunk/cumin/python/cumin: grid inventory
by croberts@fedoraproject.org
Author: croberts
Date: 2012-03-21 13:54:26 +0000 (Wed, 21 Mar 2012)
New Revision: 5256
Modified:
trunk/cumin/python/cumin/grid/slotvis.py
trunk/cumin/python/cumin/inventory/system.py
trunk/cumin/python/cumin/inventory/system.strings
Log:
Per BZ 805029, removing the slotvis functionality from cumin.
Modified: trunk/cumin/python/cumin/grid/slotvis.py
===================================================================
--- trunk/cumin/python/cumin/grid/slotvis.py 2012-03-20 15:04:22 UTC (rev 5255)
+++ trunk/cumin/python/cumin/grid/slotvis.py 2012-03-21 13:54:26 UTC (rev 5256)
@@ -20,7 +20,6 @@
super(SlotOverview, self).__init__(app, name)
self.add_tab(SlotSelector(app, "slots"))
- self.add_tab(Visualization(app, "vis"))
def render_title(self, session):
return "Slots"
Modified: trunk/cumin/python/cumin/inventory/system.py
===================================================================
--- trunk/cumin/python/cumin/inventory/system.py 2012-03-20 15:04:22 UTC (rev 5255)
+++ trunk/cumin/python/cumin/inventory/system.py 2012-03-21 13:54:26 UTC (rev 5256)
@@ -126,10 +126,7 @@
slots = SystemSlotMap(app, "system_slot_map", system)
self.add_child(slots)
-
- slot_vis = SystemSlotFlashVis(app, "system_slot_flash", system)
- self.add_child(slot_vis)
-
+
self.main_tmpl = WidgetTemplate(self, "html")
def render_title(self, session):
Modified: trunk/cumin/python/cumin/inventory/system.strings
===================================================================
--- trunk/cumin/python/cumin/inventory/system.strings 2012-03-20 15:04:22 UTC (rev 5255)
+++ trunk/cumin/python/cumin/inventory/system.strings 2012-03-21 13:54:26 UTC (rev 5256)
@@ -19,8 +19,6 @@
<h2>Memory/Load</h2>
{stats}
<br/>
- {system_slot_map}
- {system_slot_flash}
</td>
<td>
{freemem}
12 years, 1 month
r5255 - trunk/wooly/resources/plugins
by croberts@fedoraproject.org
Author: croberts
Date: 2012-03-20 15:04:22 +0000 (Tue, 20 Mar 2012)
New Revision: 5255
Modified:
trunk/wooly/resources/plugins/jqplot.highlighter.js
trunk/wooly/resources/plugins/jqplot.highlighter.min.js
Log:
Manually merging a fix that will force the tooltips to go away when you mouse off of the chart.
Modified: trunk/wooly/resources/plugins/jqplot.highlighter.js
===================================================================
--- trunk/wooly/resources/plugins/jqplot.highlighter.js 2012-03-19 19:51:28 UTC (rev 5254)
+++ trunk/wooly/resources/plugins/jqplot.highlighter.js 2012-03-20 15:04:22 UTC (rev 5255)
@@ -29,6 +29,7 @@
*/
(function($) {
$.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
+ $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMove]);
/**
* Class: $.jqplot.Highlighter
@@ -451,4 +452,4 @@
}
}
}
-})(jQuery);
\ No newline at end of file
+})(jQuery);
Modified: trunk/wooly/resources/plugins/jqplot.highlighter.min.js
===================================================================
--- trunk/wooly/resources/plugins/jqplot.highlighter.min.js 2012-03-19 19:51:28 UTC (rev 5254)
+++ trunk/wooly/resources/plugins/jqplot.highlighter.min.js 2012-03-20 15:04:22 UTC (rev 5255)
@@ -54,4 +54,4 @@
*
*
*/
-(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(k,j,n,m,l){var h=l.plugins.highlighter;var o=l.plugins.cursor;if(h.show){if(m==null&&h.isHighlighting){var i=h.highlightCanvas._ctx;i.clearRect(0,0,i.canvas.width,i.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;i=null}else{if(m!=null&&l.series[m.seriesIndex].showHighlight&&!h.isHighlighting){h.isHighlighting=true;h.currentNeighbor=m;if(h.showMarker){a(l,m)}if(h.showTooltip&&(!o||!o._zoom.started)){g(l,l.series[m.seriesIndex],m)}if(h.bringSeriesToFront){l.moveSeriesToFront(m.seriesIndex)}}else{if(m!=null&&h.isHighlighting&&h.currentNeighbor!=m){if(l.series[m.seriesIndex].showHighlight){var i=h.highlightCanvas._ctx;i.clearRect(0,0,i.canvas.width,i.canvas.height);h.isHighlighting=true;h.currentNeighbor=m;if(h.showMarker){a(l,m)}if(h.showTooltip&&(!o||!o._zoom.started)){g(l,l.series[m.seriesIndex],m)}if(h.bringSeriesToFront){l.moveSeriesToFront(m.seriesIndex)}}}}}}}})(jQuery);
\ No newline at end of file
+(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(k,j,n,m,l){var h=l.plugins.highlighter;var o=l.plugins.cursor;if(h.show){if(m==null&&h.isHighlighting){var i=h.highlightCanvas._ctx;i.clearRect(0,0,i.canvas.width,i.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;i=null}else{if(m!=null&&l.series[m.seriesIndex].showHighlight&&!h.isHighlighting){h.isHighlighting=true;h.currentNeighbor=m;if(h.showMarker){a(l,m)}if(h.showTooltip&&(!o||!o._zoom.started)){g(l,l.series[m.seriesIndex],m)}if(h.bringSeriesToFront){l.moveSeriesToFront(m.seriesIndex)}}else{if(m!=null&&h.isHighlighting&&h.currentNeighbor!=m){if(l.series[m.seriesIndex].showHighlight){var i=h.highlightCanvas._ctx;i.clearRect(0,0,i.canvas.width,i.canvas.height);h.isHighlighting=true;h.currentNeighbor=m;if(h.showMarker){a(l,m)}if(h.showTooltip&&(!o||!o._zoom.started)){g(l,l.series[m.seriesIndex],m)}if(h.bringSeriesToFront){l.moveSeriesToFront(m.seriesIndex)}}}}}}}})(jQuery);
\ No newline at end of file
12 years, 1 month