CMS 3D CMS Logo

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