CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HTMLExport.py
Go to the documentation of this file.
1 import sys
2 import os
3 import os.path
4 import logging
5 import random
6 import json
7 
9 import FWCore.ParameterSet.Config as cms
10 import FWCore.ParameterSet.Modules as mod
11 import FWCore.ParameterSet.Types as typ
12 import FWCore.ParameterSet.Mixins as mix
13 
14 from Vispa.Plugins.ConfigEditor.ConfigDataAccessor import ConfigDataAccessor
15 from FWCore.GuiBrowsers.FileExportPlugin import FileExportPlugin
16 
17 
18 def elem(elemtype, innerHTML='', html_class='', **kwargs):
19  if html_class: #since 'class' cannot be used as a kwarg
20  kwargs['class'] = html_class
21  args = ' '.join(['%s="%s"' % i for i in kwargs.items()])
22  if args:
23  return "<%s %s>%s</%s>\n" % (elemtype, args, innerHTML, elemtype)
24  else:
25  return "<%s>%s</%s>\n" % (elemtype, innerHTML, elemtype)
26 
27 def get_jquery():
28  jquery_file = os.path.join(os.path.dirname(sys.modules[__name__].__file__), 'jquery-1.6.2.min.js')
29  if os.path.exists(jquery_file):
30  return elem('script', open(jquery_file).read(), type='text/javascript')
31  else:
32  return elem('script', type='text/javascript', src=JQUERY)
33 
34 JQUERY = "http://code.jquery.com/jquery-1.6.2.min.js"
35 LXR = "http://cmslxr.fnal.gov/lxr/ident?"
36 CVS = "http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/"
37 CMSLOGO = "http://cms.cern.ch/iCMS/imgs/icms/CMSheader_left.gif"
38 
39 CSS_TEMPLATE =\
40 """
41 body {border-width:0;margin:0}
42 #header {width:100%;height:10%;background-color:#000}
43 #mlist {position:absolute;width:32%;top:10%;left:0;height:85%;overflow:auto;padding-left:20px}
44 #mview {position:absolute;width:65%;height:85%;top:10%;left:35%;overflow:auto}
45 #footer {position:absolute;top:95%;width:100%;height:5%;background-color:#000}
46 #cmslogo {float:left;vertical-align:middle;margin:5px}
47 #head_filedir {float:left;vertical-align:middle;margin:5px}
48 #searcharea {float:right;vertical-align:middle;margin-top:3px;margin-right:5px;position:relative}
49 #head_dirname {color:#ccc;font-size:12}
50 #head_filename {color:#fff;font-weight:bold;font-size:16}
51 #searchhider {display:none;position:relative;top:-10px}
52 #searchhider a {color:#fff;text-decoration:none}
53 #searchresult {display:none;-moz-border-radius:10px;border-radius:10px;border:2px solid #999;background-color:#ccc;padding:5px;z-index:1000;position:relative;height:700%}
54 #searchscroll {overflow:scroll;height:100%;width:100%}
55 #searchresult div {margin:3px;padding:2px}
56 .searchfrom {color:#999;font-size:small}
57 
58 #mview_header {font-weight:bold;font-size:16;background-color:#cc6;-moz-border-radius:10px;border-radius:10px;margin-top:3px;padding:5px}
59 #mview_header span {border-radius:5px;-moz-border-radius:5px;padding-left:5px;padding-top:2px;margin-top:2px;margin-left:5px}
60 #mview_subheader {background-color:#ffffcc;-moz-border-radius:10px;border-radius:10px;margin-top:3px;padding:5px}
61 #mview_pset {background-color:#ffffcc;-moz-border-radius:10px;border-radius:10px;margin-top:3px;padding:5px}
62 .mview_label {color:#999}
63 .mview_value {border-radius:5px;-moz-border-radius:5px;padding-left:5px;padding-top:2px;margin-top:2px;margin-left:5px;background-color:#cc6}
64 .mview_value a {text-decoration:none}
65 .mview_value span {display:inline-block}
66 
67 #footer_crumbs {float:left;font-size:small;font-weight:bold;color:#fff}
68 #footer_crumbs span {color:#000}
69 #footer_about {float:right}
70 #footer_about a {text-decoration:none;font-weight:bold;color:#fff}
71 
72 .csearch {background-color:#fff}
73 
74 .seq_contain {position:relative;left:-20px}
75 .seq_toggle {position:absolute;left:5px;top:2px;width:15px;vertical-align:middle;text-align:center;font-weight:bold;font-size:20}
76 .seq_right {position:relative;left:20px;border-radius:5px;-moz-border-radius:5px;padding-left:5px;padding-top:3px;margin-top:3px;width:auto;display:inline-block}
77 .seq_label {font-weight:bold;border-radius:5px;-moz-border-radius:5px;padding:3px 1px;display:inline-block;border-width:1px;border-style:solid}
78 .seq_expand {display:none;padding-left:20px}
79 
80 .module {position:relative;border-radius:5px;-moz-border-radius:5px;padding-left:3px;padding-top:1px;margin-top:2px;padding-right:3px;padding-bottom:1px;margin-right:2px;display:inline-block;border-width:1px;border-style:solid}
81 
82 .path {background-color:#3cf;border-color:#3cf}
83 .endpath {background-color:#9cf;border-color:#9cf}
84 .sequence {background-color:#99f;border-color:#99f}
85 .edanalyzer {background-color:#f00;border-color:#f00}
86 .edproducer {background-color:#0f0;border-color:#0f0}
87 .edfilter {background-color:#ff0;border-color:#ff0}
88 .outputmodule {background-color:#f0f;border-color:#f0f}
89 .source {background-color:#f9c;border-color:#f9c}
90 .service {background-color:#f96;border-color:#f96}
91 .sources {background-color:#fcc;border-color:#fcc}
92 .services {background-color:#fc6;border-color:#fc6}
93 .essource {background-color:#9cc;border-color:#9cc}
94 .esproducer {background-color:#3c9;border-color:#3c9}
95 .esprefer {background-color:#096;border-color:#096}
96 .essources {background-color:#9fc;border-color:#9fc}
97 .esproducers {background-color:#3f9;border-color:#3f9}
98 .esprefers {background-color:#0c6;border-color:#0c6}
99 .unknown_type {background-color:#ccc;border-color:#ccc}
100 
101 .used {border-radius:5px;-moz-border-radius:5px;padding:2px 5px;margin-top:2px;margin-right:5px;border-width:1px;border-style:solid}
102 .member {border-radius:5px;-moz-border-radius:5px;padding:2px 5px;margin-top:2px;margin-right:5px;border-width:1px;border-style:solid}
103 
104 .clickable {cursor:pointer}
105 span.clickable:hover {border-color:#fff}
106 div.module.clickable:hover {border-color:#fff}
107 div.seq_label.clickable:hover {border-color:#fff}
108 
109 .pset {border:2px solid #000;background-color:#ffffcc;font-size:small;border-collapse:collapse}
110 .pset td {border-width:1px;border-color:#ccc; border-style:solid none;margin:0;padding:2px 4px}
111 .pset_label {font-weight:bold}
112 .pset_type {color:#aaa}
113 
114 .pset_vector {list-style-type:none;border:1px solid #000;padding-left:5px;margin:1px}
115 .pset_int {font-family:courier;color:blue}
116 .pset_double {font-family:courier;color:purple}
117 .pset_string {font-family:courier;color:brown}
118 .pset_bool {font-family:courier;color:#f0f}
119 .pset_inputtag {font-family:courier}
120 .pset_othertype {font-family:courier}
121 .pset_placehold {display:none;color:#aaa}
122 
123 #about_dialog {position:absolute;width:60%;height:40%;top:30%;left:20%;border-radius:10px;-moz-border-radius:10px;color:#fff;background-color:#00f;border:5px solid #003;display:none;text-align:center}
124 """
125 
126 JS_TEMPLATE =\
127 """
128 var modules = {};
129 var sequences = {};
130 var pset_keys = {};
131 var pset_values = {};
132 var crumbs = [];
133 var n_results = 0;
134 var last_search = "";
135 
136 var cvsroot = "%(cvs)s";
137 var lxrroot = "%(lxr)s";
138 if (data.process.cmssw) {
139  lxrroot = lxrroot + "v=" + data.process.cmssw + ";";
140 }
141 
142 function parse_data() {
143  function _pset_visitor(pset, context) {
144  var keys = [];
145  var values = [];
146  for (var i in pset) {
147  var item = pset[i];
148  var name = context + item.label;
149  if (item.type == 'PSet') {
150  result = _pset_visitor(item.value, name+'.');
151  keys.concat(result.keys);
152  values.concat(result.values);
153  } else if (item.type == 'VPSet') {
154  for (var j in item.value) {
155  result = _pset_visitor(item.value[j], name+'.');
156  if (j==0) {
157  keys.concat(result.keys); //assume they all have equivalent structure
158  }
159  values.concat(result.values);
160  }
161  } else if (item.type == 'VInputTag') {
162  keys.push(name);
163  for (var j in item.value) {
164  values.push(item.value[j][0].toString()); //only modulename
165  }
166  } else if (item.type == 'InputTag') {
167  keys.push(name);
168  values.push(item.value[0].toString());
169  } else if (item.list) {
170  keys.push(name);
171  for (var j in item.value) {
172  values.push(item.value[j].toString());
173  }
174  } else {
175  keys.push(name);
176  values.push(item.value.toString());
177  }
178  }
179  return {keys:keys, values:values};
180  }
181  function _path_visitor(path) {
182  if (path.path) {
183  sequences[path.label] = path;
184  for (var child in path.path) {
185  _path_visitor(path.path[child]);
186  }
187  } else {
188  _module_visitor(path);
189  }
190  }
191  function _module_visitor(module) {
192  modules[module.label] = module;
193  if (module.pset) {
194  var result = _pset_visitor(module.pset, '');
195  pset_keys[module.label] = result.keys;
196  pset_values[module.label] = result.values;
197  }
198  }
199  function _handle_flat(modlist) {
200  for (var i in modlist) {
201  _module_visitor(modlist[i]);
202  }
203  }
204  _handle_flat(data.source);
205  _handle_flat(data.services);
206  _handle_flat(data.essources);
207  _handle_flat(data.esproducers);
208  _handle_flat(data.esprefers);
209  for (var p in data.paths) {var path = data.paths[p]; _path_visitor(path);}
210  for (var p in data.endpaths) {var path = data.paths[p]; _path_visitor(path);}
211 }
212 
213 function ensure_visible(name) {
214  if (! $("#"+name).is(":visible")) {
215  $("#"+name).parents(".seq_expand").each(function() {
216  if (! $(this).is(":visible")) {
217  var id = $(this).attr("id").slice(7);
218  toggle_sequence(id);
219  }
220  });
221  }
222  $("#mlist").animate({"scrollTop": $("#"+name).position().top}, 1000);
223 }
224 
225 function show_module(name) {
226  var module = modules[name];
227  if (module) {
228  add_breadcrumb("module", name);
229  ensure_visible(name);
230  show_mview(module);
231  }
232 }
233 
234 function show_sequence(name) {
235  var sequence = sequences[name];
236  if (sequence) {
237  add_breadcrumb("sequence", name);
238  ensure_visible(name);
239  show_mview(sequence);
240  }
241 }
242 
243 function show_mview(module) {
244  function build_memberlist(memberof) {
245  var new_html = "";
246  for (var i in memberof) {
247  var sequence = sequences[memberof[i]];
248  if (sequence) {
249  new_html += "<span class='clickable member "+sequence.type.toLowerCase()+"' onclick='show_sequence(\\""+sequence.label+"\\");'>"+sequence.label+"</span>";
250  } else {
251  new_html += "<span class='member unknown_type'>"+memberof[i]+"</span>";
252  }
253  }
254  return new_html;
255  }
256  function build_uselist(uses) {
257  var new_html = "";
258  for (var i in uses) {
259  var module = modules[uses[i]];
260  if (module) {
261  new_html += "<span class='clickable used "+module.type.toLowerCase()+"' onclick='show_module(\\""+module.label+"\\");'>"+module.label+"</span>";
262  } else {
263  new_html += "<span class='used unknown_type'>"+uses[i]+"</span>";
264  }
265  }
266  return new_html;
267  }
268  function build_pset(pset, context, toplevel) {
269  var typemap = {"string": "string", "double": "double", "int32": "int", "int64": "int", "uint32": "int", "uint64": "int", "bool": "bool"};
270  if (! toplevel) {
271  var new_html = "<span class='pset_placehold clickable' id='placehold_"+context+"' onclick='pset_toggle(\\""+context+"\\");'>("+pset.length.toString()+" hidden)</span><table id='content_"+context+"' class='pset'>";
272  } else {
273  var new_html = "<table class='pset'>";
274  }
275  for (var i in pset) {
276  var context2 = context + "_" + i.toString();
277  var item = pset[i];
278  if (item.untracked) {
279  var itemtype = "cms.untracked."+item.type;
280  } else {
281  var itemtype = "cms."+item.type;
282  }
283  if (item.list) {
284  itemtype += "[" + item.value.length.toString() + "]";
285  new_html += "<tr><td class='pset_label'>"+item.label+"</td><td class='pset_type clickable' onclick='pset_toggle(\\""+context2+"\\");'>"+itemtype+"</td><td>";
286  } else if (item.type == 'PSet') {
287  new_html += "<tr><td class='pset_label'>"+item.label+"</td><td class='pset_type clickable' onclick='pset_toggle(\\""+context2+"\\");'>"+itemtype+"</td><td>";
288  } else {
289  new_html += "<tr><td class='pset_label'>"+item.label+"</td><td class='pset_type'>"+itemtype+"</td><td>";
290  }
291 
292  if (item.type == 'PSet') {
293  new_html += build_pset(item.value, context2);
294  } else if (item.type == 'VPSet') {
295  new_html += "<span class='pset_placehold clickable' id='placehold_"+context2+"' onclick='pset_toggle(\\""+context2+"\\");'>("+item.value.length.toString()+" hidden)</span><ul class='pset_vector' id='content_"+context2+"'>";
296  for (var j in item.value) {
297  new_html += "<li>"+build_pset(item.value[j], context2+"_"+j.toString())+"</li>";
298  }
299  new_html += "</ul>";
300  } else if (item.type == 'VInputTag') {
301  new_html += "<span class='pset_placehold clickable' id='placehold_"+context2+"' onclick='pset_toggle(\\""+context2+"\\");'>("+item.value.length.toString()+" hidden)</span><ul class='pset_vector' id='content_"+context2+"'>";
302  for (var j in item.value) {
303  var tag = item.value[j];
304  var link = build_uselist([tag[0]]);
305  if (tag[1] || tag[2]) {
306  new_html += "<li><span class='pset_inputtag'>"+link+":"+tag[1]+":"+tag[2]+"</span></li>";
307  } else {
308  new_html += "<li><span class='pset_inputtag'>"+link+"</span></li>";
309  }
310  }
311  new_html += "</ul>";
312  } else if (item.type == 'InputTag') {
313  var tag = item.value;
314  var link = build_uselist([tag[0]]);
315  if (tag[1] || tag[2]) {
316  new_html += "<span class='pset_inputtag'>"+link+":"+tag[1]+":"+tag[2]+"</span>";
317  } else {
318  new_html += "<span class='pset_inputtag'>"+link+"</span>";
319  }
320  } else if (item.list) {
321  new_html += "<span class='pset_placehold clickable' id='placehold_"+context2+"' onclick='pset_toggle(\\""+context2+"\\");'>("+item.value.length.toString()+" hidden)</span><ul class='pset_vector' id='content_"+context2+"'>";
322  var cmstype = item.type.slice(1);
323  if (typemap[cmstype]) {
324  var css = typemap[cmstype];
325  } else {
326  var css = "othertype";
327  }
328  for (var j in item.value) {
329  new_html += "<li><span class='pset_"+css+"'>"+item.value[j]+"</span></li>";
330  }
331  new_html += "</ul>";
332  } else {
333  var cmstype = item.type;
334  if (typemap[cmstype]) {
335  var css = typemap[cmstype];
336  } else {
337  var css = "othertype";
338  }
339  new_html += "<span class='pset_"+css+"'>"+item.value+"</span>";
340  }
341  new_html += "</td></tr>";
342  }
343  new_html += "</table>";
344  return new_html;
345  }
346  var header = "<span class='used "+module.type.toLowerCase()+"'>"+module.label+"</span>";
347  $("#mview_header").html(header);
348  var table_html = "<tr><td class='mview_label'>Module Type:</td><td class='mview_value'>"+module.type+"</td></tr>";
349  if (module.file && module.line) {
350  table_html += "<tr><td class='mview_label'>Defined in:</td><td class='mview_value'><a href='"+cvsroot+module.file+"'>"+module.file+"</a>:"+module.line+"</td></tr>";
351  } else if (module.file) {
352  table_html += "<tr><td class='mview_label'>Defined in:</td><td class='mview_value'><a href='"+cvsroot+module.file+"'>"+module.file+"</a></td></tr>";
353  }
354  if (module.class) {
355  table_html += "<tr><td class='mview_label'>Module Class:</td><td class='mview_value'><a href='"+lxrroot+"i="+module.class+"'>"+module.class+"</a></td></tr>";
356  }
357  if (module.uses) {
358  table_html += "<tr><td class='mview_label'>Uses:</td><td class='mview_value'>"+build_uselist(module.uses)+"</td></tr>";
359  }
360  if (module.usedby) {
361  table_html += "<tr><td class='mview_label'>Used by:</td><td class='mview_value'>"+build_uselist(module.usedby)+"</td></tr>";
362  }
363  if (module.memberof) {
364  table_html += "<tr><td class='mview_label'>Member of:</td><td class='mview_value'>"+build_memberlist(module.memberof)+"</td></tr>";
365  }
366  $("#mview_table").html(table_html);
367  if (module.pset) {
368  $("#mview_pset").html(build_pset(module.pset, "pset", true));
369  $("#mview_pset").find("tr,li").filter(":even").css({"background-color": "#ffa"});
370  $("#mview_pset").find("tr,li").filter(":odd").css({"background-color": "#ffc"});
371  $("#mview_pset").find('[id^="content_"]').each(function() {
372  var id = $(this).attr("id").slice(8);
373  if ($(this).children().size() > 5) {
374  pset_toggle(id);
375  }
376  });
377  } else {
378  $("#mview_pset").html("");
379  }
380 }
381 
382 function pset_toggle(item) {
383  if ($("#content_"+item).is(":visible")) {
384  $("#content_"+item).hide("fast");
385  $("#placehold_"+item).show("fast");
386  } else {
387  $("#content_"+item).show("fast");
388  $("#placehold_"+item).hide("fast");
389  }
390 }
391 
392 function add_breadcrumb(itemtype, item) {
393  if (crumbs.length > 0 && crumbs[crumbs.length-1][1] == item) {
394 
395  } else {
396  if (crumbs.push([itemtype, item]) > 5) {
397  crumbs = crumbs.slice(1);
398  }
399  }
400  var new_html = "";
401  for (var crumb in crumbs) {
402  var c = crumbs[crumb];
403  if (c[0] == "module") {
404  var module = modules[c[1]];
405  if (module) {
406  var css = "used clickable "+module.type.toLowerCase();
407  } else {
408  var css = "used unknown_type";
409  }
410  new_html += "&lt; <span class='"+css+"' onclick='show_module(\\"" + c[1] + "\\");'>" + c[1] + "</span>";
411  } else if (c[0] == "sequence") {
412  var sequence = sequences[c[1]];
413  if (sequences) {
414  var css = "used clickable "+sequence.type.toLowerCase();
415  } else {
416  var css = "used unknown_type";
417  }
418  new_html += "&lt; <span class='"+css+"' onclick='show_sequence(\\"" + c[1] + "\\");'>" + c[1] + "</span>";
419  } else if (c[0] == "search") {
420  new_html += "&lt; <span class='used clickable csearch' onclick='do_search(\\"" + c[1] + "\\");'>\\"" + c[1] + "\\"?</span>";
421  }
422  }
423  $("#footer_crumbs").html(new_html);
424 }
425 
426 function toggle_sequence(sequence) {
427  if ($("#expand_"+sequence).is(":visible")) {
428  $("#expand_"+sequence).hide("fast");
429  $("#toggle_"+sequence).text("+");
430  } else {
431  $("#expand_"+sequence).show("fast");
432  $("#toggle_"+sequence).text("-");
433  }
434 }
435 
436 function build_mlist() {
437  function build_path(path) {
438  if (path.path) {
439  var new_html = "<div class='seq_contain'><div class='seq_toggle clickable' id='toggle_"+path.label+"'>+</div><div class='seq_right "+path.type.toLowerCase()+"'><div id='"+path.label+"' class='seq_label "+path.type.toLowerCase()+"'>"+path.label+"</div><div class='seq_expand' id='expand_"+path.label+"'>";
440  for (var child in path.path) {
441  new_html += build_path(path.path[child]);
442  }
443  new_html += "</div></div></div>";
444  return new_html;
445  } else {
446  return build_module(path);
447  }
448  }
449  function build_module(module) {
450  return "<div id='"+module.label+"' class='module "+module.type.toLowerCase()+"'>"+module.label+"</div>";
451  }
452  var new_html = "";
453  if (data.source) {
454  new_html += build_path({"label":"Source", "type": "Sources", "path": data.source});
455  }
456  if (data.services) {
457  new_html += build_path({"label":"Services", "type": "Services", "path": data.services});
458  }
459  if (data.paths) {
460  for (var path in data.paths) {
461  new_html += build_path(data.paths[path]);
462  }
463  }
464  if (data.endpaths) {
465  for (var path in data.endpaths) {
466  new_html += build_path(data.endpaths[path]);
467  }
468  }
469  if (data.essources) {
470  new_html += build_path({"label":"ESSources", "type": "ESSources", "path": data.essources});
471  }
472  if (data.esproducers) {
473  new_html += build_path({"label":"ESProducers", "type": "ESProducers", "path": data.esproducers});
474  }
475  if (data.esprefers) {
476  new_html += build_path({"label":"ESPrefers", "type": "ESPrefers", "path": data.esprefers});
477  }
478  $("#mlist").html(new_html);
479  $("#mlist").find(".seq_toggle").each(function() {
480  $(this).click(function() {
481  var id=$(this).attr("id").slice(7);
482  toggle_sequence(id);
483  });
484  });
485  $("#mlist").find(".seq_label").each(function() {
486  $(this).click(function() {show_sequence($(this).attr("id"));});
487  $(this).addClass("clickable");
488  });
489  $("#mlist").find(".module").each(function() {
490  $(this).click(function() {show_module($(this).attr("id"));});
491  $(this).addClass("clickable");
492  });
493 }
494 
495 function do_search(query) {
496  if (! query) {return;}
497  add_breadcrumb("search", query);
498  var results = {modules:[], modclass:[], modfile:[], sequences:[], seqfile:[], keys:[], values:[]};
499  var pattern = new RegExp(query, "gi");
500  for (var i in modules) {
501  if (i.search(pattern) != -1) {
502  results.modules.push(i);
503  }
504  if (modules[i].class.search(pattern) != -1) {
505  results.modclass.push(i);
506  }
507  if (modules[i].file) {
508  if (modules[i].file.search(pattern) != -1) {
509  results.modfile.push(i);
510  }
511  }
512  }
513  for (var i in sequences) {
514  if (i.search(pattern) != -1) {
515  results.sequences.push(i);
516  }
517  if (sequences[i].file) {
518  if (sequences[i].file.search(pattern) != -1) {
519  results.seqfile.push(i);
520  }
521  }
522  }
523  for (var i in pset_keys) {
524  for (var j in pset_keys[i]) {
525  if (pset_keys[i][j].search(pattern) != -1) {
526  results.keys.push(i);
527  }
528  }
529  }
530  for (var i in pset_values) {
531  for (var j in pset_values[i]) {
532  if (pset_values[i][j].search(pattern) != -1) {
533  results.values.push(i);
534  }
535  }
536  }
537  var new_html = '';
538  function _module_div(name, extra) {
539  var new_html = '';
540  var module = modules[name];
541  if (modules[name]) {
542  var module = modules[name];
543  var onclick = "show_module(\\""+module.label+"\\");toggle_search();";
544  } else if (sequences[name]) {
545  var module = sequences[name];
546  var onclick = "show_sequence(\\""+module.label+"\\");toggle_search();";
547  } else {
548  return '';
549  }
550  var label = name.replace(pattern, "<b>$&</b>");
551  new_html += "<div><span class='used clickable "+module.type.toLowerCase()+"' onclick='"+onclick+"'>"+label+"</span><span class='searchfrom'>("+extra+")</span></div>";
552  return new_html;
553  }
554  var hitlist = [];
555  var searchmap = {"module name":results.modules, "module class":results.modclass, "module file":results.modfile, "module pset key":results.keys, "module pset value":results.values, "sequence name":results.sequences, "sequence file":results.seqfiles};
556  for (var i in searchmap) {
557  for (var j in searchmap[i]) {
558  if (hitlist.indexOf(searchmap[i][j]) == -1) {
559  new_html += _module_div(searchmap[i][j], i);
560  hitlist.push(searchmap[i][j]);
561  }
562  }
563  }
564  n_results = hitlist.length;
565  last_search = query;
566  $("#searchscroll").html(new_html);
567  $("#searchinput").val("search");
568  if ($("#searchhider").is(":hidden")) {$("#searchhider").show("fast");}
569  toggle_search(true);
570 }
571 
572 function toggle_search(force) {
573  if ($("#searchresult").is(":hidden") || force==true) {
574  $("#searchresult").show("slow");
575  $("#searchhider a").html("Hide search results");
576  } else {
577  $("#searchresult").hide("slow");
578  $("#searchhider a").html("Show results for <b>"+last_search+"</b> ("+n_results.toString()+")");
579  }
580 }
581 
582 function about() {
583  $("#about_dialog").toggle("slow");
584 }
585 
586 $(document).ready(function() {
587  parse_data();
588  build_mlist();
589  $('#searchinput').focus(function() {if ($(this).val() == 'search') {$(this).val('');}});
590  $('#searchsubmit').click(function(event) {event.preventDefault();do_search($('#searchinput').val());});
591 });
592 """ % dict(cvs=CVS, lxr=LXR)
593 
594 PAGE_TEMPLATE =\
595 """
596 <html>
597 <head>
598 <title>%(title)s</title>
599 <style type="text/css">
600 %(css)s
601 </style>
602 %(jquery)s
603 <script type="text/javascript">
604 var data = %(json)s;
605 %(js)s
606 </script>
607 </head>
608 <body>
609 <div id="header">
610  <div id="cmslogo"><img src="%(cmslogo)s" alt="CMS Logo" height=48 width=48></img></div>
611  <div id="head_filedir">
612  <div id="head_dirname">%(dirname)s</div>
613  <div id="head_filename">%(filename)s</div>
614  </div>
615  <div id="searcharea">
616  <div>
617  <form id="searchform">
618  <input id="searchinput" type="text" value="search">
619  <input id="searchsubmit" type="submit" value="Search">
620  </form>
621  </div>
622  <div id='searchhider'><a href='#' onclick='toggle_search();'></a></div>
623  <div id='searchresult'>
624  <div id='searchscroll'></div>
625  </div>
626  </div>
627 </div>
628 <div id="mlist"></div>
629 <div id="mview">
630  <div id="mview_header"></div>
631  <div id="mview_subheader">
632  <table id="mview_table"></table>
633  </div>
634  <div id="mview_pset"></div>
635 </div>
636 <div id="footer">
637  <div id="footer_crumbs"></div>
638  <div id="footer_about"><a href='#' onclick='about();'>About</a></div>
639 </div>
640 <div id="about_dialog" onclick='about();'>
641  <div><h2>CMSSW configuration-to-html converter</h2></div>
642  <div>Written by Gordon Ball (Imperial College)</div>
643  <div>Uses CMSSW Config Editor and jQuery</div>
644 </div>
645 </body>
646 </html>
647 """
648 
649 
650 
651 
653 
654  plugin_name = 'HTML Export'
655  file_types = ('html', )
656 
657  def __init__(self):
658  FileExportPlugin.__init__(self)
659 
660  def export(self, data, filename, filetype):
661  with open(filename, 'w') as f:
662  f.write(self.produce(data))
663 
664  def produce(self, data):
665  return PAGE_TEMPLATE % dict(title=data._filename, jquery=get_jquery(),
666  css=CSS_TEMPLATE, js=JS_TEMPLATE, dirname='.',
667  filename=data._filename, json=self.data_to_json(data),
668  cmslogo=CMSLOGO)
669 
670 
671  def data_to_json(self, data):
672  cmssw = None
673  if 'CMSSW_BASE' in os.environ:
674  cmssw = os.environ['CMSSW_BASE'].split('/')[-1]
675  elif 'CMSSW_RELEASE_BASE' in os.environ:
676  cmssw = os.environ['CMSSW_RELEASE_BASE'].split('/')[-1]
677  result = {'process': {'name': data.process().name_() if data.process() else '(no process)', 'src': data._filename, 'cmssw':cmssw}}
678  toplevel = data.children(data.topLevelObjects()[0]) if data.process() else data.topLevelObjects()
679  for tlo in toplevel:
680  children = data.children(tlo)
681  label = tlo._label
682  if label in ('source', 'services'):
683  result[label] = [{'class':data.classname(child), 'pset':self.pset_to_json(child.parameters_()), 'type':data.type(child), 'label':data.classname(child)} for child in children]
684  elif label in ('essources', 'esproducers', 'esprefers'):
685  result[label] = [self.module_to_json(data, child) for child in children]
686  elif label in ('paths', 'endpaths'):
687  result[label] = [self.path_to_json(data, child) for child in children]
688  return json.dumps(result, indent=4)
689 
690  def pset_to_json(self, pset):
691  result = []
692  for k, v in pset.items():
693  typename = v.pythonTypeName().split('.')[-1]
694  item = {'label': k, 'type': typename}
695  if not v.isTracked():
696  item['untracked'] = True
697  if typename == 'PSet':
698  item['value'] = self.pset_to_json(v.parameters_())
699  elif typename == 'VPSet':
700  item['value'] = [self.pset_to_json(vv.parameters_()) for vv in v]
701  item['list'] = True
702  elif typename == 'VInputTag':
703  v_it = []
704  for vv in v:
705  if type(vv) == cms.InputTag:
706  v_it.append(vv)
707  elif type(vv) == str:
708  v_it.append(cms.InputTag(vv))
709  else:
710  raise "Unsupported type in VInputTag", type(vv)
711  item['value'] = [(vv.moduleLabel, vv.productInstanceLabel, vv.processName) for vv in v_it]
712  item['list'] = True
713  elif typename == 'InputTag':
714  item['value'] = [v.moduleLabel, v.productInstanceLabel, v.processName]
715  elif isinstance(v, mix._ValidatingListBase):
716  item['value'] = [str(vv) for vv in v]
717  item['list'] = True
718  else:
719  item['value'] = v.pythonValue()
720  result += [item]
721  return result
722 
723  def module_to_json(self, data, module):
724  return {
725  'label':data.label(module),
726  'class':data.classname(module),
727  'file':data.pypath(module),
728  'line':data.lineNumber(module),
729  #'package':data.pypackage(module),
730  'pset':self.pset_to_json(module.parameters_()),
731  'type':data.type(module),
732  'uses':data.uses(module),
733  'usedby':data.usedBy(module),
734  'memberof':data.foundIn(module)
735  }
736 
737  def path_to_json(self, data, path):
738  children = data.children(path)
739  if data.isContainer(path):
740  json_children = [self.path_to_json(data, child) for child in children]
741  return {'type':data.type(path), 'label':data.label(path),
742  'path':json_children, 'memberof': data.foundIn(path),
743  'file': data.pypath(path), 'line': data.lineNumber(path)}
744  #'package': data.pypackage(path)}
745  else:
746  return self.module_to_json(data, path)
747 
748 
749 
750 
752  options_types={}
753  plugin_name='HTML Export (Static)'
754  file_types=('html',)
755  def __init__(self):
756  FileExportPlugin.__init__(self)
757 
758  def produce(self,data):
759  def elem(elemtype,innerHTML='',html_class='',**kwargs):
760  if html_class:
761  kwargs['class']=html_class
762  return "<%s %s>%s</%s>\n" % (elemtype,' '.join(['%s="%s"'%(k,v) for k,v in kwargs.items()]),innerHTML,elemtype)
763  def div(innerHTML='',html_class='',**kwargs):
764  return elem('div',innerHTML,html_class,**kwargs)
765 
766  def htmlPSet(pset):
767  def linkInputTag(tag):
768  inputtag=''
769  if isinstance(tag,typ.InputTag):
770  inputtag = tag.pythonValue()
771  else:
772  inputtag = tag
773  if len(str(tag))==0:
774  inputtag = '""'
775  return inputtag
776 
777  pset_items_html=''
778  for k,v in pset.items():
779  if isinstance(v,mix._ParameterTypeBase):
780  if isinstance(v,mix._SimpleParameterTypeBase):
781  item_class='other'
782  if isinstance(v,typ.bool):
783  item_class='bool'
784  if isinstance(v,typ.double):
785  item_class='double'
786  if isinstance(v,typ.string):
787  item_class='string'
788  if isinstance(v,(typ.int32, typ.uint32, typ.int64, typ.uint64)):
789  item_class='int'
790  pset_items_html+=elem('tr',
791  elem('td',k,'param-name')
792  +elem('td',v.pythonTypeName(),'param-class')
793  +elem('td',v.pythonValue(),'param-value-%s'%item_class),
794  'pset-item'
795  )
796  if isinstance(v,typ.InputTag):
797  pset_items_html+=elem('tr',
798  elem('td',k,'param-name')
799  +elem('td',v.pythonTypeName(),'param-class')
800  +elem('td',linkInputTag(v),'param-value-inputtag'),
801  'pset-item'
802  )
803  if isinstance(v,typ.PSet):
804  pset_html = ''
805  if len(v.parameters_())==0:
806  pset_items_html+=elem('tr',
807  elem('td',k,'param-name')
808  +elem('td',v.pythonTypeName(),'param-class')
809  +elem('td','(empty)','label'),
810  'pset-item'
811  )
812  else:
813  pset_items_html+=elem('tr',
814  elem('td',k,'param-name')
815  +elem('td',v.pythonTypeName(),'param-class')
816  +elem('td',htmlPSet(v.parameters_())),
817  'pset-item'
818  )
819  if isinstance(v,mix._ValidatingListBase):
820  list_html = ''
821  if len(v)==0:
822  list_html = elem('li','(empty)','label')
823  else:
824  if isinstance(v,typ.VInputTag):
825  for vv in v:
826  list_html += elem('li',linkInputTag(vv),'param-value-inputtag pset-list-item')
827  elif isinstance(v,typ.VPSet):
828  for vv in v:
829  list_html += elem('li',htmlPSet(vv.parameters_()),'pset-list-item')
830  else:
831  item_class='other'
832  if isinstance(v,typ.vbool):
833  item_class='bool'
834  if isinstance(v,typ.vdouble):
835  item_class='double'
836  if isinstance(v,typ.vstring):
837  item_class='string'
838  if isinstance(v,(typ.vint32,typ.vuint32,typ.vint64,typ.vuint64)):
839  item_class='int'
840  for vv in v:
841  if len(str(vv))==0:
842  vv = "''"
843  list_html += elem('li',vv,'pset-list-item param-value-%s'%item_class)
844  pset_items_html+=elem('tr',
845  elem('td',k,'param-name')
846  +elem('td','%s[%s]'%(v.pythonTypeName(),len(v)),'param-class')
847  +elem('td',elem('ol',list_html,'pset-list')),
848  'pset-item'
849  )
850 
851 
852  return elem('table',pset_items_html,'pset')
853 
854  def htmlModule(mod):
855  mod_label_html = div(elem('a',data.label(mod),'title',name=data.label(mod)),'module_label '+data.type(mod),onClick='return toggleModuleVisible(\'%s\')'%('mod_%s'%(data.label(mod))))
856 
857  mod_table = elem('table',
858  elem('tr',elem('td','Type','label')+elem('td',data.type(mod)))
859  +elem('tr',elem('td','Class','label')+elem('td',data.classname(mod))),
860  'module_table')
861 
862  mod_pset = htmlPSet(mod.parameters_())
863 
864  mod_content_html = div(mod_table+mod_pset,'module_area',id='mod_%s'%data.label(mod))
865  return div(mod_label_html+mod_content_html,'module',id='module_'+data.label(mod))
866 
867  def htmlPathRecursive(p):
868  children = data.children(p)
869  if children:
870  seq_name='Sequence'
871  if isinstance(p,sqt.Path):
872  seq_name='Path'
873  if isinstance(p,sqt.EndPath):
874  seq_name='EndPath'
875  seq_label_html = div(seq_name+' '+elem('span',data.label(p),'title')+' '+elem('span','[%s children hidden]'%len(children),'hidden',id='seq_hidden_%s'%data.label(p)),'sequence_label',onClick='return toggleSequenceVisible(\'%s\')'%data.label(p),id='seq_label_%s'%data.label(p))
876  seq_inner_content_html = ''.join([htmlPathRecursive(c) for c in children])
877  seq_content_html = div(seq_inner_content_html,'sequence_area',id='seq_%s'%data.label(p))
878  return div(seq_label_html+seq_content_html,'sequence')
879  else:
880  return htmlModule(p)
881 
882  toplevel={}
883 
884 
885 
886  filter_html = elem('span','Filter '+
887  elem('input',type='text',width=50,onkeyup="return doFilter();",id='input-filter'),
888  'right label')
889 
890  header_html = div('Config File Visualisation'+filter_html,'header')
891 
892  if data.process():
893  for tlo in data.children(data.topLevelObjects()[0]):
894  children = data.children(tlo)
895  if children:
896  toplevel[tlo._label]=children
897  path_html=''
898  if 'paths' in toplevel:
899  for path in toplevel['paths']:
900  path_html += div(htmlPathRecursive(path),'path')
901 
902  file_html = div(elem('span','Process:')
903  +elem('span',data.process().name_(),'title')
904  +elem('span',data._filename,'right'),
905  'file')
906  head_html = elem('head',elem('title',data.process().name_()))
907  else:
908  toplevel['sequences']=[]
909  toplevel['paths']=[]
910  toplevel['modules']=[]
911  for tlo in data.topLevelObjects():
912  if data.type(tlo)=='Sequence':
913  toplevel['sequences']+=[tlo]
914  if data.type(tlo)=='Path':
915  toplevel['paths']+=[tlo]
916  if data.type(tlo) in ('EDAnalyzer','EDFilter','EDProducer','OutputModule'):
917  toplevel['modules']+=[tlo]
918 
919  path_html = ''
920  sequence_html = ''
921  module_html = ''
922  for path in toplevel['paths']:
923  path_html += div(htmlPathRecursive(path),'path')
924  for sequence in toplevel['sequences']:
925  sequence_html += htmlPathRecursive(sequence)
926  for module in toplevel['modules']:
927  module_html += htmlModule(module)
928  file_html = div(elem('span',data._filename,'right'),'file')
929  path_html += sequence_html
930  path_html += module_html
931  head_html = elem('head',elem('title',data._filename))
932  footer_html = div('gordon.ball','footer')
933 
934 
935 
936  style_html = elem('style',
937  """
938  .title{font-weight:bold}
939  .label{color:grey}
940  .header{position:fixed;top:0px;left:0px;width:100%;background:#33cc00;font-weight:bold;font-size:120%}
941  .footer{position:fixed;bottom:0px;left:0px;width:100%;background:#33cc00;text-align:right}
942  .canvas{padding:40px 10px 40px 10px}
943  .file{position:relative;background:#bbb;width:100%;padding-left:5px}
944  .right{position:absolute;right:5px}
945  .sequence{border:1px solid #aaa}
946  .sequence:hover{border 1px solid #00ffff}
947  .sequence_label{background:lightskyblue;padding-left:5px}
948  .sequence_label:hover{background:#fff}
949  .sequence_label_hidden{background:grey;padding-left:5px}
950  .sequence_area{padding:5px 0px 5px 5px}
951  .edproducer{border:1px solid red;background-image:url('edproducer.png');background-position:center left;background-repeat:no-repeat;padding:0px 0px 0px 40px}
952  .edfilter{border:1px solid green;background-image:url('edfilter.png');background-position:center left;background-repeat:no-repeat;padding:0px 0px 0px 40px}
953  .edanalyzer{border:1px solid blue;background-image:url('edanalyzer.png');background-position:center left;background-repeat:no-repeat;padding:0px 0px 0px 40px}
954  .outputmodule{border:1px solid green;background-image:url('outputmodule.png');background-position:center left;background-repeat:no-repeat;padding:0px 0px 0px 40px}
955  .module{}
956  .module_label:hover{background:#ccc;position:relative}
957  .module_area{display:none;padding:5px 0px 15px 15px;background:beige}
958  .pset{border-spacing:10px 1px;border:1px solid black}
959  .pset-item{}
960  .pset-list{list-style-type:none;margin:0px;padding:2px 2px 2px 2px;border:1px solid grey}
961  .pset-list-item{border-top:1px solid lightgrey;border-bottom:1px solid lightgrey}
962  .param-name{font-weight:bold}
963  .param-class{color:grey}
964  .param-value-int{font-family:courier;color:blue}
965  .param-value-double{font-family:courier;color:purple}
966  .param-value-string{font-family:courier;color:brown}
967  .param-value-bool{font-family:courier;color:#f0f}
968  .param-value-inputtag{font-family:courier;color:red}
969  .param-value-other{font-family:courier}
970  .path{}
971  .hidden{display:none}
972  """,
973  type='text/css')
974 
975  script_html = elem('script',
976  """
977  function toggleModuleVisible(id) {
978  var elem = document.getElementById(id);
979  if (elem.style.display=='block') {
980  elem.style.display='none';
981  } else {
982  elem.style.display='block';
983  }
984  }
985 
986  function toggleSequenceVisible(id) {
987  var area_elem = document.getElementById('seq_'+id);
988  var hidden_elem = document.getElementById('seq_hidden_'+id);
989  var label_elem = document.getElementById('seq_label_'+id);
990  if (area_elem.style.display=='none') {
991  area_elem.style.display='block';
992  hidden_elem.style.display='none';
993  label_elem.className = 'sequence_label';
994  } else {
995  area_elem.style.display='none';
996  hidden_elem.style.display='block';
997  label_elem.className = 'sequence_label_hidden';
998  }
999  }
1000 
1001  function doFilter() {
1002  var text = document.getElementById('input-filter').value;
1003  var regex = new RegExp(text);
1004  for (var i=0;i<document.all.length;i++) {
1005  if (document.all(i).id.substr(0,7)=="module_") {
1006  var elem = document.all(i);
1007  var elem_name = elem.id.substr(7);
1008  if (regex.test(elem_name)) {
1009  elem.style.display='block';
1010  } else {
1011  elem.style.display='none';
1012  }
1013  }
1014  }
1015  }
1016  """,
1017  type='text/javascript')
1018 
1019  body_html = elem('body',script_html+header_html+footer_html+div(file_html+path_html,'canvas'))
1020 
1021  return elem('html',head_html+style_html+body_html)
1022 
1023  def export(self,data,filename,filetype):
1024  #if not data.process():
1025  # raise "HTMLExport requires a cms.Process object"
1026 
1027  html = self.produce(data)
1028 
1029  if filetype=='html':
1030  htmlfile = open(filename,'w')
1031  htmlfile.write(html)
1032  htmlfile.close()
def get_jquery
Definition: HTMLExport.py:27
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
double split
Definition: MVATrainer.cc:139