5 import FWCore.ParameterSet.Config
as cms
10 def __init__(self,cfgFile,html,quiet,helperDir,fullDir):
17 self.
_reg = re.compile(
"['>]")
23 "DictParent":{
"creator":
"dictCreate",
"simple":
True},
24 "ModuleSeqParent":{
"creator":
"modSeqCreate",
"simple":
False},
25 "ProdConsumParent":{
"creator":
"prodConCreate",
"simple":
False}
27 for name,x
in six.iteritems(self.
_parents):
30 self.
_type =
"%stypes.js"%(fullDir)
32 self.
_config = ConfigDataAccessor.ConfigDataAccessor()
33 self._config.open(cfgFile)
38 topObjs = self._config.topLevelObjects()
42 with open(self.
_type,
'w')
as f:
43 f.write(
"var %s=%s"%(ty,genericTypes))
48 fN = fileName.split(
"./")[-1].
split(
".")[0]
51 self._config.process().name_(), fN)
55 print "---Nothing found for file %s."\
56 " No computation done.---"%(fileName)
63 name = self._config.label(each)
64 kids = self._config.children(each)
66 if(
not self.
_quiet):
print name,
"is empty." 70 if(ty
is ConfigDataAccessor.ConfigFolder):
73 if(
not self.
_quiet):
print "computing %s.."%(name)
74 if(isinstance(kids[0], seq._ModuleSequenceType)):
82 if(self.
_quiet):
print "calculated: %s."%(
", ".
join(calc))
89 json = [topLevel,theDataFile]
90 cap = namep.capitalize()
93 with open(fullDataFile,
'w')
as data:
101 name = self._config.label(item)
104 key = self._config.label(item)
107 self._config.fullFilename(item), self._config.type(item),
"")
109 with open(fullTopLevel,
'w')
as other:
114 gen, spec = re.sub(self.
_reg,
"",
115 str(item.__class__)).
split(
".")[-2:]
121 mo =self._config.motherRelations(item)
122 dau = self._config.daughterRelations(item)
124 self._mother[name] = [self._config.label(i)
for i
in mo]
126 self.
_daughter[name] = [self._config.label(i)
for i
in dau]
131 always= types =
False 135 if(globalType ==
"modules"):
139 always = types =
True 141 if(always
or not types):
147 name = self._config.label(item)
149 if(isinstance(item,cms._Parameterizable)):
151 elif(isinstance(item,cms._ValidatingListBase)):
153 if(isinstance(item,cms._TypedParameterizable)):
158 self._config.fullFilename(item),
159 self._config.type(item), oType)
160 with open(fullDataFile,
'w')
as dataFile:
169 if(option): basicName = option%(name)
170 else: basicName =
"%s.js"%(name)
171 return (basicName,
"%s%s"%(self.
_theDir,basicName))
175 if(
not self._mother
and not self.
_daughter):
177 for name,theDict
in {
"producer":self._mother,
178 six.iteritems(
"consumer":self.
_daughter}):
183 with open(fulldataFile,
'w')
as moth:
186 jsonfiles =
" ".
join([
"%s%s"%(self.
_helperDir,x)
for x
in jsonfiles])
188 temp[
"data-base"] = base
189 temp[
"data-files"] = jsonfiles
190 self._data[name] = temp
195 base =
"obj= Object.create(new %s(%s));" 204 for pname,x
in six.iteritems(self.
_parents):
205 simple = base%(pname,name)
206 filename,fullfilename= x[
"cfile"]
207 self._allJSFiles.append(filename)
210 with open(fullfilename,
'w')
as setUp:
211 setUp.write(format%(x[
"creator"],paramName,self.
_load(
212 name,paramName,simple)))
215 paramName=[
"modules",
"topLevel"]
216 complexOne = base%(pname,
"%s,%s"%(name, secName))
217 with open(fullfilename,
'w')
as setUp:
218 setUp.write(format%(x[
"creator"],
", ".
join(paramName),
219 self.
_load(name,paramName[0],
220 self.
_load(secName, paramName[1],complexOne))))
225 loadJSON(%s).done(function(%s){\n%s\n}); 226 """%(param,name,inner)
230 exVar =
'this.%(key)sKey= "%(key)s";' 234 * @param {String} the key to the dictionary. 235 * @returns {String || Integer} result from dictionary if found else 0. 237 %(name)s.prototype.get%(key)s = function(key){ 238 return this.getFeature(key,this.%(key)sKey); 241 search =
"""%(name)s.prototype.search%(key)s = function(reg,term,replce){ 242 return this.generalSearch(reg,term,replce,this.%(key)sKey); 247 * Uses the list of parents names to go further into 248 * the lists in the dictionry, and give the last parents children. 249 * @param {Array} the names of parents to look through. 250 * First parent should be a key to the dictionary. 251 * @param {Integer} the index where the elusive parameter is. Needed incase 252 * we have a list with muultiple parameters of the same name. 254 * @returns {Array} the resulting children from the last parent. 256 DictParent.prototype.getInnerParams = function(parents, index){ 257 var currentList = this.data[parents[0]][this.%(key)sKey]; 259 var siblingsOfTarget=[] 260 for(var i=1; i < parents.length;i++){ 261 for(var p=0; p < currentList.length;p++){ 262 if(currentList[p][0]==parents[i]){ 263 targetList = currentList[p] 264 siblingsOfTarget=currentList 265 var found = targetList[1]; 271 if(p != index)targetList=siblingsOfTarget[index] 279 fileName, fullfileName= data[
"pfile"]
280 for feature
in dictFeatures:
281 d = {
"key": feature,
"name": name}
284 if(feature ==
"Parameters"):
288 self._allJSFiles.append(fileName)
289 with open(fullfileName,
'w')
as parent:
292 Base Object for dictionaries. 293 To use, create a dictParent obj, 294 then use Object.create to create a new obj 295 then you can change some variables/add functions 296 and have the inherited functions. 298 function %(name)s(data){ 303 * Finds the desired feature from a dictionary. 304 * @param {String} the key to the dictionary. 305 * @param {String} the feature we want from the dictionary. 306 * @returns {String || Integer} result from dictionary if found else 0. 308 %(name)s.prototype.getFeature = function(key, feature){ 309 var temp = this.data[key]; 310 if(temp) return temp[feature]; 313 DictParent.prototype.getData = function(){ 319 * Gives the keys from desired dictionary. 320 * @returns {Array} all keys from the dictionary. 322 %(name)s.prototype.getKeys = function(){ 323 return Object.keys(this.data); 325 %(name)s.prototype.generalSearch = function(reg,term,repl,feature, d){ 329 var x= d[key][feature] 330 if(x.indexOf(term)>-1){ 331 matches[key] = x.replace(reg,repl) 338 * Gives the generic type for a given type. 339 * @param {String} type 340 * @returns {String} the generic type 342 function getGenericType(type){ 343 return %(gen)s[type]; 345 """%{
"theVars":variables,
"getterFunctions":functs,
346 "gen": typeName,
"name":name})
352 * Gives the direct children 353 * @param {String} a path name 354 * @returns {Array} list of names of the the children. 356 %(name)s.prototype.getModules = function(name){ 357 return this.topLevelData[name][this.ParametersKey]; 359 %(name)s.prototype.getTopFile = function(key){ 360 return this.topLevelData[key][this.FileKey]; 362 %(name)s.prototype.getData = function(){ 363 return [this.topLevelData, this.data]; 365 %(name)s.prototype.searchType = function(reg,term,replce){ 366 return this.generalSearch(reg,term,replce,this.TypeKey, this.topLevelData); 368 %(name)s.prototype.searchFile = function(reg,term,replce){ 369 return this.generalSearch(reg,term,replce,this.FileKey, this.topLevelData); 378 * Gives the direct children 379 * @param {String} a path name 380 * @returns {Array} list of names of the the children. 382 %(name)s.prototype.getModules = function(name){ 383 return this.topLevelData[name]; 385 %(name)s.prototype.getTopFile = function(key){ 386 return this.getFile(key); 388 %(name)s.prototype.getData = function(){ 389 return [this.topLevelData, this.data]; 391 // Producer and consumer have different structure to rest. 392 // Dont have file and type with them.. 393 // to get file and type we need to take each name, 394 //look up the moduledata and find matches. 395 %(name)s.prototype.generalSearch = function(reg,term,repl, feature){ 397 for (var key in this.topLevelData){ 398 var x = this.data[key][feature] 399 if(x.indexOf(term)>-1){ 400 matches[key] = x.replace(reg,repl) 405 %(name)s.prototype.typeSearch = function(reg,term,replce){ 406 return this.generalSearch(reg,term,replce,this.TypeKey); 408 %(name)s.prototype.fileSearch = function(reg,term,replce){ 409 return this.generalSearch(reg,term,replce,this.FileKey); 417 fileName, fullfilename= data[
"pfile"]
418 self._allJSFiles.append(fileName)
421 Base object for thing of the type: 422 It also inherits from DictParent. 424 function %(name)s(data,topLevel, nameList,indexList){ 426 this.topLevelData=topLevel;// e.g. pathNames to module names 427 this.fixedNameList = nameList; // e.g.names of paths 429 %(name)s.prototype = new %(dict)s(this.data); 431 %(name)s.prototype.getKeys = function(){ 432 return Object.keys(this.topLevelData) 435 with open(fullfilename,
'w')
as parent:
436 parent.write(all%{
"name": name,
"dict": self.
_dictP})
443 for (name,valType)
in six.iteritems(parameters):
444 theT= (valType.configTypeName() if(
445 hasattr(valType,
"configTypeName"))
else "").
split(
" ",1)[-1]
446 temp = re.sub(
"<|>|'",
"",
str(type(valType)))
447 generic, spec = temp.split(
".")[-2:]
450 if(isinstance(valType,cms._Parameterizable)):
452 elif(isinstance(valType,cms._ValidatingListBase)):
455 if(isinstance(valType,cms._SimpleParameterTypeBase)):
456 value = valType.configValue()
459 value = valType.pythonValue()
462 theList.append(value)
463 if(theT !=
"double" and theT !=
"int" and not isinstance(valType, str)):
464 if(
not valType.isTracked()):
465 theList.append(
"untracked")
476 if(
not VList):
return "" 478 if(isinstance(first,cms._Parameterizable)
or 479 isinstance(first,cms._ValidatingListBase)):
481 if(isinstance(first,cms._ValidatingListBase)):
485 if(member.hasLabel_()):
486 name = member.label()
488 name = member.configTypeName()
490 if(
not anotherVList):
494 temp = re.sub(
"<|>|'",
"",
str(type(member)))
495 generic, spec = temp.split(
".")[-2:]
497 innerList.append(spec)
498 outerList.append(innerList)
500 elif(isinstance(first,cms._SimpleParameterTypeBase)):
501 return ",".
join(i.configValue()
for i
in VList)
502 elif(isinstance(first,cms._ParameterTypeBase)):
503 return ",".
join(i.pythonValue()
for i
in VList)
507 outcome =
",".
join(
str(i)
for i
in VList)
510 return "Unknown types" 513 dictFeatures=[
"Parameters",
"Type",
"File",
"oType"]
517 d[dictFeatures[0]] = params
518 d[dictFeatures[1]] = typ
519 d[dictFeatures[2]] = fil
520 d[dictFeatures[3]] = oType
548 return re.sub(self.
_reg,
"",
str(type(val))).
split(
".")[-2:]
551 Do Module Objects e.g. producers etc 553 def _doModules(self,modObj, dataFile, seq, seqs, currentName, innerSeq):
555 name = self.config.label(modObj)
558 self._underPath.append(name)
560 seqs[currentName].
append([name])
563 if(name
not in self._modulesToPaths.keys()):
565 filename = modObj._filename.split(
"/")[-1]
566 generic,specific = self.
_getType(modObj)
569 filename, specific, modObj.type_())
578 if(isinstance(value,cms._Module)):
581 elif(isinstance(value,cms._Sequenceable)):
582 generic,specific = self.
_getType(value)
584 if(isinstance(value, cms._ModuleSequenceType)):
587 name = self.config.label(value)
594 self._underPath.append(name)
595 self.
_seqs[name] = []
600 name = value.__str__()
604 self._underPath.append(value.__str__())
605 if(name
not in self.
_done):
607 self._df.write(
',"%s":%s'%(name,
JSONFormat(d)))
608 self._done.append(name)
611 if(isinstance(value,cms._Module)):
613 elif(isinstance(value,cms._Sequenceable)):
616 if(isinstance(value, cms._ModuleSequenceType)):
618 name = self.config.label(value)
619 if(name
in self.
_oldNames):self._oldNames.remove(name)
625 if(name
not in self.
_done):
626 generic,specific = self.
_getType(value)
628 self._df.write(
',"%s":%s'%(name,
JSONFormat(d)))
629 self._done.append(name)
634 def __init__(self,name,js,items,theDir, helperDir, pN,pFN):
635 jqName =
"%scfgJS.js"%(theDir)
636 jqLocal =
"%scfgJS.js"%(helperDir)
637 css =
"%sstyle.css"%(theDir)
638 cssL =
"%sstyle.css"%(helperDir)
646 <script type="text/javascript" src="%s"></script>""" 647 return "\n".
join([x%(i)
for i
in js])
651 <option value=%(n)s data-base="%(d)s" data-files="%(f)s"> %(n)s</option>""" 652 s= [l%({
"n":x,
"f":y[
"data-files"],
"d":y[
"data-base"]})
653 for x,y
in six.iteritems(items)]
657 b =
"""<option value="%(name)s" data-base="%(d)s">%(name)s</option> """ 658 return "\n ".
join([b%({
"name": x,
"d":y[
"data-base"]})
659 for x,y
in six.iteritems(items)])
662 with open(name,
'w')
as htmlFile:
663 htmlFile.write(
"""<!DOCTYPE html>\n<html>\n <head> 664 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > 665 <title>cfg-browser</title>\n <script type="text/javascript" 666 src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> 667 </script>\n %(s)s\n %(css)s\n </head>\n <body> 668 <div class="topBox topSpec"> 669 <input type="submit" value="Edit" id="editMode" autocomplete="off" 670 disabled/>\n <div class="helpLinks"> 671 <a href="#" class="nowhere" id="helpMouse" data-help="#help">help 673 <a href="mailto:susie.murphy@cern.ch?Subject=CfgBrowserhelp" 674 target="_top">Contact</a>\n </div>\n <div id="help"> </div> 675 <span id="mode">Normal Mode</span> 676 <div class="topBox hideTopBox">hide</div>\n </div> 677 <a id="topOfPage"></a>\n <br/><br/><br/>\n <div class="outerBox"> 678 <div class="boxTitle"> Pick\n <div class="dottedBorder"> 679 <form onsubmit="return false;">\n <select id="showType"> 680 %(items)s\n </select>\n <br/><br/> 681 <input type="submit" id="docSubmit" value="submit"> 682 </form>\n </div>\n </div> 683 <div class="boxTitle"> Pick\n <div class="dottedBorder"> 684 <form onsubmit="return false;"> 685 <input type="text" id="searchWord"/> 686 <select id="searchType">\n %(search)s 687 </select> \n <span id="addSearch"> </span> 689 <input type="submit" value="Search" id="search"/> 690 <input type="checkbox" id="rmHilight" value="File"/> 691 <span>Don't show highlights</span>\n </form> 692 </div>\n </div>\n </div> \n <br/> 693 <input type="checkbox" id="ShowFiles" value="File"/> 694 <span>Show file names</span>\n <br/><br/>\n <script> 695 document.getElementById("searchType").selectedIndex = -1;\n </script> 696 <div id="posty"> </div>\n <br/>\n <div id="current"></div> 697 <br/>\n <div id="searchCount"></div>\n <div id="attachParams"></div> 698 <div class="rightScroll">\n <a href="#topOfPage">Back to Top</a> 699 <p>\n <a id="hide" href="javascript:;" >Hide All</a>\n </p> 700 </div>\n </body>\n</html>\n"""%{
701 "s":scrip,
"css":css,
"items":items,
"search":search})
704 with open(css,
'w')
as cssfile:
706 *{\n font-family:"Lucida Grande", Tahoma, Arial, Verdana, sans-serif;\n} 707 .topBox{\n opacity:0.9;\n background-color:#dfdfdf;\n}\n.topSpec{ 708 position:fixed;\n top:0;\n left:0;\n width:100%;\n height:2.5em; 709 border-radius:.9em;\n}\n.hideTopBox, .showTopBox{\n position:absolute; 710 top:2.5em;\n right:2%;\n width:auto;\n height:auto;\n padding: 0.2em; 711 font-weight:bold;\n cursor:pointer;\n border-radius:.3em;\n}\n.negative{ 712 position:absolute;\n right:0;\n text-decoration:none; 713 font-weight:bold;\n color:#565656;\n}\n#mode{\n position:absolute; 714 right:50%; \n color:#808080;\n font-size:12pt;\n}\n#editMode,#normalMode{ 715 position:absolute;\n left:.3em;\n top:.5em;\n}\n#save{ 716 position:absolute;\n top:.5em;\n}\n.helpLinks{\n position:absolute; 717 right:1.3em;\n width:6.2em;\n text-align:right;\n} 718 /* divs for the Pick and Search boxes.*/\n.outerBox{\n width:100%; 719 overflow:hidden;\n}\n.boxTitle{\n float:left;\n margin-left:.6em; 720 color:#A9A9A9;\n}\n.dottedBorder{\n width:25em;\n height:4em; 721 border:.1em dashed #A9A9A9;\n padding:.6em;\n}\n/* -- */ 722 /* Right scroll box. */\n.rightScroll{\n position:fixed;\n bottom:50%; 723 right:0; \n width:6.2em;\n text-align:right;\n border:.1em solid #A9A9A9; 724 opacity:0.4;\n background-color:#F0FFF0;\n}\n#hide{\n cursor:default; 725 opacity:0.2;\n}\nli{\n padding-left:.8em;\n}\nul{\n list-style-type:none; 726 padding-left:.1em;\n}\n/* Icons before list items. */\n.expand:before{ 727 content:'›';\n}\n.expanded:before{\n content:'ˇ';\n} 728 .expand:before,.expanded:before{\n float:left;\n margin-right:.6em;\n} 729 .expand,.expanded{\n cursor:pointer;\n}\n/* colours of each. */ 730 .Path,.EndPath{\n color:#192B33;\n}\n.Modules{ \n color:#800080;\n} 731 .SequenceTypes{\n color:#0191C8\n}\n.paramInner,.Types{\n color:#4B4B81;\n} 732 .param{\n color:#9999CC;\n margin-left:.8em;\n cursor:default; \n}\n.value{ 733 color:#0000FF;\n}\n.type{\n color:#00CCFF;\n} 734 /* Header for what's showing */\n#current{\n color:#808080;\n font-size:12pt; 735 text-decoration:underline; \n}\n/* help settings */\n#help{ 736 position:absolute;\n display:none;\n background:#ccc;\n border:.1em solid; 737 width:19em;\n right:15em;\n top:1.2em;\n}\nh5{\n font-style:normal; 738 text-decoration:underline; \n margin:0;\n font-size:9pt;\n}\nh6{ 739 margin:0;\n color:#666666;\n}\n#attachParams{\n color:#192B33;\n}\nem{ 740 color:#FFA500;\n}\n.cellEdit{\n border:.1em dotted #A9A9A9;\n cursor: text; 742 return """<link href="%s" rel="stylesheet" \ 743 type="text/css"/>"""%(cssLocal)
746 with open(name,
'w')
as jq:
748 \n$(document).ready(function(){ \n//Object used to get all details 749 var processName="%s";\nvar processFileName ="%s"; 750 var CURRENT_OBJ;\nvar searchShowing= false;\nvar showParams = false 751 var alreadyShowing = false\nvar topClass = "Top"\nvar searching = false 752 var expandDisable = false;\nvar hideVisible=false //nothing is expanded. 753 // ---\n/*\n Functions used to abstract away name of function calls 754 on the object (CURRENT_OBJ). 755 (i.e. so function names can easily be changed.)\n*/ 756 function baseParams(inputs){\n return CURRENT_OBJ.getParameters(inputs);\n} 757 function baseInnerParams(inputs, index){ 758 return CURRENT_OBJ.getInnerParams(inputs, index);\n} 759 function baseType(inputs){\n return CURRENT_OBJ.getType(inputs);\n} 760 function baseFile(inputs){\n return CURRENT_OBJ.getFile(inputs);\n} 761 function baseTopFile(inputs){\n return CURRENT_OBJ.getTopFile(inputs);\n} 762 // --- Show some inital data operations ---\n/*\n Show something new!\n*/ 763 $(document).on('click', '#docSubmit', function(e){ 764 var $elem = $('#showType :selected') 765 //get the function we want and the lists\n setCURRENT_OBJ($elem)\n 766 addData($elem.attr("value"), CURRENT_OBJ.getKeys());\n searchShowing= false; 767 });\n/*\n Add data to the html.\n*/ 768 function addData(docType, data, dataNames){ 769 $("#editMode").removeAttr("disabled"); \n var dataNames = dataNames || data; 770 if(alreadyShowing){\n //need to click cancel if its active. 771 goNormal($("#normalMode"));\n if(!searching)$("#searchCount").html("") 772 invisibleHide()\n paramOptions(false) 773 $(document.getElementsByTagName('body')).children('ul').remove();\n } 774 $("#current").html(docType)\n var gen = getGenericType(docType) 775 var ty = docType\n if(gen != undefined){\n var gL = gen.toLowerCase() 776 if(gL=="modules"||gL=="types") var ty= gen;\n } 777 var $LI = $(document.createElement('li') 778 ).addClass("expand").addClass(ty).addClass(topClass); 779 docType= docType.toLowerCase()\n var showTypes = false\n showParams = true 780 switch(docType){\n case "producer":\n case "consumer": 781 showParams = false\n paramOptions(true) 782 $LI.addClass("Modules")\n showTypes = true\n break; 783 case "modules":\n $LI.addClass("Modules")\n showTypes = true 784 //showParams = true\n break;\n } 785 var $UL = addTopData(data,$LI,showTypes,dataNames)\n alreadyShowing = true; 786 $UL.appendTo('#attachParams');\n}\n/* 787 Used to add the top level data to html.\n*/ 788 function addTopData(data,$LI,types,dataName){ 789 var dataName = dataName || data; 790 var $UL = $(document.createElement('ul'));\n var doNormalFile = false; 791 var files = document.getElementById("ShowFiles").checked\n if(files){ 792 try{\n baseTopFile(dataName[0])\n }\n catch(e){ 793 doNormalFile = true;\n }\n }\n for(var i=0; i < data.length;i++){ 794 var n = dataName[i]\n var t = data[i]; 795 if(types)t += " ("+baseType(n)+")"\n if(files){ 796 if(doNormalFile)var file = baseFile(n) 797 else var file = baseTopFile(n)\n t += " ("+file+")"} 798 $UL.append($LI.clone().attr("data-name",n).html(t));\n }\n return $UL;\n} 799 // --- end of inital showing data operations ---\n 800 // --- search operations ---\n 801 //$(document).on('click', "[name='searchTerm1']", function(e){ 802 //$(document).on('click', "#searchType option", function(e){ 803 $(document).on('click', '#searchType', function(e){\n $("#addSearch").empty() 804 var tname= $(this).text().toLowerCase();\n var sel= jQuery('<select/>', { 805 id:"searchType2"\n }) 806 var li = (tname =="modules"|| tname == "producer"|| tname == "consumer")? 807 ["Name", "Type", "File"]: ["Name", "File"]\n for(var i in li){ 808 var x = li[i]\n jQuery('<option/>',{\n value:x,\n text:x 809 }).appendTo(sel)\n }\n sel.appendTo("#addSearch");\n});\n/* 810 Current search only searches for top level things.\n*/ 811 $(document).on('click','#search', function(e){\n searching = true 812 var first = $('#searchType :selected')\n if(first.length ==0){ 813 window.alert("Please chose a search type."); \n return;\n } 814 var doc = first.text()\n var searchTerm = $('#searchWord').val() 815 var $elem = $('option[value="'+doc+'"]')\n setCURRENT_OBJ($elem) 816 var reg = new RegExp(searchTerm, 'g') 817 if($('#rmHilight').prop('checked'))\n var fin = searchTerm\n else 818 var fin = "<em>"+searchTerm+"</em>" 819 switch($('#searchType2 :selected').text()){\n case "File": 820 $("#ShowFiles").prop('checked', true); 821 var items = CURRENT_OBJ.searchFile(reg,searchTerm,fin) 822 var matchCount = fileTypeSearch(doc,items,true)\n break; 823 case "Type":\n var items = CURRENT_OBJ.searchType(reg,searchTerm,fin) 824 var matchCount = fileTypeSearch(doc,items,false)\n break 825 case "Name":\n var matchCount = easySearch(searchTerm,reg, doc, fin) 826 }\n $("#searchCount").html(matchCount+ " found.")\n searching = false; 827 searchShowing= true;\n});\n/*\n Used when searching top level elements. 828 i.e. Module names, path names etc. 829 We dont need to delve into any dictionaries, we just use the keys.\n*/ 830 function easySearch(term,reg, doc, fin){\n var keys = CURRENT_OBJ.getKeys() 831 var matches = keys.filter(function(e, i, a){return (e.indexOf(term)>-1)}) 832 var highlights = matches.map(function(e,i,a){ 833 return e.replace(reg, fin)}) 834 addData(doc, highlights,matches)\n return matches.length\n}\n/* 835 When searching type or file names of top level elements.\n*/ 836 function fileTypeSearch(doc,items,file){ 837 var newFunct = function(name){return items[name]}\n if(file){ 838 var backup = baseFile\n var backup2 = baseTopFile 839 baseFile = newFunct \n baseTopFile = newFunct\n }\n else { 840 var backup = baseType\n baseType = newFunct\n } 841 var matches = Object.keys(items)\n addData(doc, matches)\n if(file){ 842 baseFile = backup\n baseTopFile = backup2\n }\n else baseType = backup 843 return matches.length\n}\n// --- end of search operations ---\n 844 // --- edit operations ---\n// variables needed: 845 // will contain the highest parents, where something *might* 846 // be changed in its children.\nvar $potential=[] 847 // dict, keys are parentNames and values are lists of children changed 848 // under that parent\nvar parChildNames={}\n 849 $(document).on('click', '#editMode', function(e){\n if(searchShowing) 850 var dataType = $('#searchType :selected').attr("data-base") 851 else var dataType = $('#showType :selected').attr("data-base") 852 // Temp restriction of editing SequenceTypes e.g. Paths,EndPaths etc. 853 if(dataType=="modSeqCreate"){ 854 window.alert("At the moment editing for SequenceTypes"+ 855 " has been disabled.");\n return;\n } 856 else if (dataType == "prodConCreate"){ 857 window.alert("Sorry, it is currently not possible to "+ 858 "edit producers and consumers.");\n return;\n } 859 if(CURRENT_OBJ == undefined)return; 860 // this is editing mode, turn off expansion\n expandDisable = true; 861 $("#mode")[0].textContent = "Edit Mode"\n $(this).attr("value", "Cancel"); 862 var l = ($(this).width()/ parseFloat($("body").css("font-size"))+2.5)+"em" 863 $(this).after(jQuery('<input>', {\n type:"submit", 864 value:"Save",\n id:"save"\n }).css({\n left:l\n})); 865 $(this).attr("id", "normalMode")\n makeEditable(searchShowing); 866 searchShowing = false;\n});\n/* 867 Adds in div elements to make cells editable.\n*/ 868 function makeEditable(rmSearch){\n // add editable div to everything showing. 869 var todo = jQuery.makeArray($(".Top"));\n while(todo.length){ 870 var e = $(todo.pop())\n if(rmSearch) 871 e.html(e.html().replace(/(<em>|<\/em>)/g, "")) 872 // we have the item.. lets get children 873 var kids = jQuery.makeArray(e.children()); 874 // add divs to all children.\n while(kids.length){ 875 var k = $(kids.pop())\n var tag = k.prop("tagName")\n 876 if(tag == "SPAN"){\n if(k.prop("class")!="type") 877 k.html('<div class="cellEdit" contenteditable>'+k.html()+'</div>') 878 continue\n }\n if(tag =="LI"){ 879 // add the div but dont get children 880 $(k.contents()[0]).wrap('<div class="cellEdit" contenteditable />'); 881 }\n // check if have any children 882 var moreKids = jQuery.makeArray(k.children()); 883 if(moreKids.length){\n kids = kids.concat(moreKids)\n } 884 }\n // now do current one 885 $(e.contents()[0]).wrap('<div class="cellEdit" contenteditable />');\n } 886 }\n/*\n A cell which is editable has been clicked.\n*/ 887 $(document).on('click', '.cellEdit', function(e){ 888 // we're in edit so things have a div parent over the text. 889 // so get parent to get the thing we want. 890 var $itemChanged = $(this).parent() 891 // now go up until we find greatest parent(item with class==topClass) 892 var classes = $itemChanged.attr("class")\n var $parent = $itemChanged 893 while(classes.indexOf(topClass)==-1){\n $parent = $parent.parent(); 894 classes = $parent.attr("class") || "";\n } 895 var parentName = $parent.attr("data-name"); 896 // doesnt matter if parent and child are the same. 897 var parents = Object.keys(parChildNames) 898 if(parents.indexOf(parentName)>-1){\n // already been edited. 899 var kids = parChildNames[parentName] 900 if(kids.indexOf($itemChanged.attr("data-name"))==-1){ 901 kids.push($itemChanged)\n }\n }\n else{ 902 parChildNames[parentName]=[$itemChanged]\n }\n $potential.push($parent) 903 });\n//--- end of edit operations ---\n// --- start of save operations ---\n/* 904 Save any changes.\n*/\n$(document).on('click', '#save', function(e){ 905 var allData = CURRENT_OBJ.getData();\n var oldData = allData[0] 906 goNormal($("#normalMode"));\n if(allData.length >1){ 907 var top = allData[0];\n var rest = allData[1]; 908 var changed = save(deepCopy(top),deepCopy(rest))\n }\n else{ 909 var changed = save(deepCopy(allData[0]));\n } 910 if(Object.keys(changed).length ==0){ 911 window.alert("Nothing was changed.");\n $potential=[] 912 parChildNames={}\n return \n } 913 //$('#svg_export_form > input[name=svg]').val("jhgjhg"); 914 changed["processName"]= processName 915 changed["processFileName"]= processFileName\n $("#posty").empty() 916 var form = jQuery('<form/>', {\n id:"edited_write",\n method:"POST", 917 async: "false",\n enctype: "multipart/form-data", 918 style:"display:none;visibility:hidden",\n })\n jQuery('<input/>', { 919 type:"hidden",\n name:"changed",\n value:JSON.stringify(changed), 920 }).appendTo(form)\n form.appendTo("#posty")\n $('#edited_write').submit(); 921 $potential=[]\n parChildNames={}\n});\n/* 922 Go to normal viewing mode. Discard any changes.\n*/ 923 $(document).on('click', '#normalMode', function(e){ 924 //remove all cell edit Divs\n goNormal($(this));\n //$potential =[] 925 //parChildNames={}\n});\n/*\n Couldn't find built-in deep clone or copy.\n*/ 926 function deepCopy(obj){\n if(obj instanceof Array){\n var copy=[] 927 obj.forEach(function(x,i,a){copy[i]= deepCopy(x)})\n return copy\n } 928 else if(obj instanceof Object){\n var copy ={}\n for (key in obj){ 929 copy[key] = deepCopy(obj[key])\n }\n return copy\n }\n return obj 930 }\n\n/*\n Returns a dict of everything that has changed.\n*/ 931 function save(data, restData){\n var allChanged={}\n var done=[] 932 for(var i in $potential){\n var parent = $potential[i]; 933 // we have the parent. 934 var oldParentName = $(parent).attr("data-name"); 935 //bit iffy, can have same parent name multiple times? todo 936 if(done.indexOf(oldParentName)>-1) continue\n done.push(oldParentName) 937 if(typeof restData =='undefined'){ 938 var allDict = deepCopy(data[oldParentName]) 939 var allOldData = allDict["Parameters"] 940 var childChanged = parChildNames[oldParentName] 941 var oldToNew= chil(childChanged,parent, true) 942 if(oldToNew.length ==0) continue 943 var newpar = blah(oldToNew, oldParentName, allOldData, parent, false) 944 tempDict = allDict\n tempDict["Parameters"] = allOldData 945 allChanged[newpar] = tempDict\n if(oldToNew.length>0){ 946 window.alert("Something went wrong, I did not find all changes."); 948 // we have one data for the parents and one for rest 949 var allDict = deepCopy(data[oldParentName]) 950 var allKids = allDict["Parameters"]\n var tem ={} 951 var childChanged = parChildNames[oldParentName]; 952 var oldToNew = chil(childChanged,parent, false); 953 //if(Object.keys(oldToNew).length ==0) continue 954 if(oldToNew.length ==0) continue\n for (var y in allKids){ 955 var n = allKids[y]\n var allOld2 = deepCopy(restData[n]) 956 var allOldData = allOld2["Parameters"] 957 // blah chanhes allOldData 958 var newpar = blah(oldToNew, n, allOldData, parent, true) 959 allOld2["Parameters"]= allOldData\n tem[newpar] = allOld2 960 }\n var newParentName = $(parent).contents()[0].nodeValue 961 //allChanged[newParentName]= tem\n tempDict = allDict 962 tempDict["Parameters"] = tem\n allChanged[newParentName] = tempDict 963 continue\n }\n }\n return allChanged\n}\n/* 964 These three functions are used for getting data from 965 a structure such as [{},{},{}]\n*/\nfunction getValue(list, key){\n var re=[] 966 for(x in list){\n di = list[x]\n k = Object.keys(di)[0] 967 if(k==key)re.push(di[k])\n }\n return re\n}\nfunction getKeys(list){ 968 var keys = []\n for (x in list)\n keys.push(Object.keys(list[x])[0]) 969 return keys\n}\nfunction deleteValue(list, k,d){\n var inde =-1 970 var found = false\n for(var x in list){\n var di = list[x] 971 var key = Object.keys(di)[0]\n if(key==k && di[key]==d){ 972 found = true\n inde = x\n break\n }\n } 973 if(found)list.splice(inde,1)\n}\n/* 974 allOldData will be changed with the new data.\n*/ 975 function blah(oldToNew, oldParentName, allOldData, parent){ 976 var newpar = oldParentName\n var keys = getKeys(oldToNew) 977 if(keys.indexOf(oldParentName)>-1){\n // parent is in 978 var tDatas = getValue(oldToNew,oldParentName); 979 for (var x in tDatas){\n var tData = tDatas[x] 980 if(tData["i"]==0 && tData["p"].length ==0){ 981 var newpar = tData["new"];\n // this isnt finding tData 982 deleteValue(oldToNew, oldParentName,tData);\n }\n }\n } 983 // okay so here we have everything for this parent. 984 // now need to loop through the old data and changed for new. 985 if(oldToNew.length >0){ 986 loopData(allOldData,oldToNew,[oldParentName], [0]);\n } 987 return newpar\n}\n//need to remember that current format is 988 //[name, parameters,type,optionalType]\n/*\n Loop around the data, \n*/ 989 function loopData(thelist, items, parents, pIndex){\n for(var x in thelist){ 990 var y = thelist[x]\n if(y instanceof Array){ 991 // okay if array, we have full line 992 if(typeof y[0] == "string" && y[1] instanceof Array){ 993 // this is what we want.\n var theName = y[0] 994 var rest = y[1]\n var types = [y[2]]\n if(y.length == 4) 995 types.push(y[3])\n // okay, name of this is theName == parent 996 // the index of this is x\n parents.unshift(theName) 997 pIndex.unshift(x)\n loopData(rest, items, parents, pIndex); 998 parents.shift()\n pIndex.shift() 999 rightOne(thelist,x,theName,items,parents,pIndex) 1000 for(var index in types){\n var item = types[index] 1001 rightOne(thelist,x,item,items,parents,pIndex)\n } 1003 if(y[0] instanceof Array && y[1] instanceof Array){ 1004 // y1 is a parameter\n // y2 is a parameter 1005 for(var e in y){\n loopData(y[e],items,parents,pIndex); 1006 }\n continue;\n }\n // we are here, 1007 //so we have something that does not have parameters in a list 1008 var theName = y[0]\n for(var index in y){\n if(index >0){ 1009 parents.unshift(theName) \n pIndex.unshift(x)\n } 1011 rightOne(thelist,x,item,items,parents,pIndex)\n if(index >0){ 1012 parents.shift()\n pIndex.shift()\n }\n } 1013 continue;\n }\n else { 1014 rightOne(thelist,x,y,items,parents,pIndex)\n }\n }\n}\n/* 1015 Helper function. We have a match, now change old values for new values.\n*/ 1016 function rightOne(thelist,x,y,items,parents,pIndex){ 1017 if(getKeys(items).indexOf(y)>-1){ 1018 // we know that we have a match, but are indexes the same? 1019 // index will be in the same list so we can use x 1020 var dis = getValue(items, y)\n for (inde in dis){ 1021 var di= dis[inde]\n if(x == di["i"]){ 1022 if(arrayCompare(parents, pIndex,di["p"],di["pIndex"] )){ 1023 //okay we can be sure we are changing the right thing. 1024 if(thelist[x] instanceof Array){ 1025 for(var ind in thelist[x]){\n var z = thelist[x][ind] 1026 if(y == z){\n thelist[x][ind] = di["new"] 1028 else{\n thelist[x] = di["new"]\n } 1029 deleteValue(items,y,di)\n }\n }\n }\n }\n}\n/* 1030 Returns true if arrays a1 is identical to a2 and 1031 a1Index is identical to a2Index.\n*/ 1032 function arrayCompare(a1, a1Index, a2, a2Index) { 1033 if (a1.length != a2.length)return false; 1034 for (var i = 0; i < a1.length; i++) { 1035 if (a1[i] != a2[i] || a1Index[i] != a2Index[i]) { 1036 return false;\n }\n }\n return true;\n}\n/* 1037 Take in the children that might have been changed. 1038 If something has been changed, adds to a dictionary 1039 dictionary format is [data-name]={ 1040 "new": newvalue, "i":data-index, "p":[parentNames], 1041 "pIndex": [indicies of parents]} 1042 TODO, need a new format, what if children have 1043 the same data-name and both are changed?\n*/ 1044 function chil (childChanged, parent, addParent){\n var oldToNew=[] 1045 for (var x in childChanged){\n var child = childChanged[x] 1046 // we need to check if the child has been changed. 1047 var oldval = child.attr("data-name"); 1048 var isSpan = child.prop("tagName") == "SPAN"\n var newval = isSpan ? 1049 child.contents().text(): child.contents()[0].nodeValue; 1050 //remove any enclosing brackets 1051 newval = newval.trim().replace(/\(.*\)$/, ""); 1052 oldval = oldval.trim().replace(/\(.*\)$/, ""); 1053 if(oldval==newval)continue\n else{ 1054 //child has been changed.\n //we want to keep 4 pieces of data. 1055 //1. old name, new name\n //2. data-index 1056 //3. list of direct parents.\n //4. indexes of all parents. 1057 var inner ={}\n inner["new"] = newval; 1058 //depends if it was a span or not. Span means we use parents. 1059 inner["i"]= (isSpan? child.parent().attr("data-index"): 1060 child.attr("data-index")) || 0\n var allP = child.parents() 1061 var pNames =[]\n var pIndex =[] 1062 for(var y=0; y < allP.length; y++){\n var p = $(allP[y]) 1063 var tag = p.prop("tagName") 1064 if(p.attr("data-name") == parent.attr("data-name")){ 1065 if(addParent){\n pNames.push(parent.attr("data-name")) 1066 pIndex.push(parent.attr("data-index") || 0);\n } 1067 break;\n }\n else if(tag == "LI"){ 1068 pNames.push(p.attr("data-name")); 1069 pIndex.push(p.attr("data-index") || 0);\n }\n } 1070 inner["p"] = pNames\n inner["pIndex"] = pIndex\n var t={} 1071 t[oldval]= inner\n oldToNew.push(t)\n } 1072 } // end of childchanged loop\n return oldToNew\n} 1073 // --- end of save operations --- 1074 // --- Expand and show more data operations ---\n/* 1075 Used when in edit mode to stop any items being added to the webpage. 1076 More items added after edit mode- they wont be editable, and when you 1077 click to edit something it loads its children.\n*/ 1078 $(document).on('click','.expand, .expanded', function(event){ 1079 if(expandDisable){\n event.stopImmediatePropagation();\n }\n});\n/* 1080 Retrieves and expands elements whose objects have multiple lists 1081 (i.e. onese who's data-base !=simpleData)\n*/ 1082 $(document).on('click', '.Consumer.expand,.Producer.expand,' 1083 +'.Path.expand,.EndPath.expand ',function(event){ 1084 var allModules = CURRENT_OBJ.getModules($(this).attr('data-name')); 1085 var UL = addParams(this,allModules)\n $(this).append(UL); 1086 event.stopPropagation();\n});\n/*\n Adds parameters onto objects.\n*/ 1087 $(document).on('click','.Modules.expand,.SequenceTypes,.Types.expand' 1088 , function(event){\n if(showParams){\n addParams(this);\n } 1089 event.stopPropagation();\n});\n/*\n Hides/Shows children from class param. 1090 */ \n$(document).on('click', '.paramInner.expand, .paramInner.expanded', 1091 function(event){\n if($(this).children('ul').length ==0){ 1092 // find parents\n var parents = findParents(this) 1093 var result = baseInnerParams(parents,parseInt( 1094 $(this).attr("data-index")) )[1] 1095 addParams(this, result);\n }\n else{ 1096 //children already added, so just hide/show. 1097 $(this).children('ul').toggle();\n }\n event.stopPropagation(); 1098 });\n/*\n Find the parents of a child.\n*/\nfunction findParents(child){ 1099 var parents =[$(child).attr("data-name")] 1100 var theParent = $(child).attr("data-parent") 1101 while(theParent !=undefined){ \n var child = $(child).parent(); 1102 if(child.prop("tagName")=="UL") continue; 1103 parents.unshift(child.attr("data-name")); 1104 theParent = child.attr("data-parent");\n }\n return parents\n}\n/* 1105 Helper function: returns filename appended onto val.\n*/ 1106 function getFile(theName){\n var f = baseFile(theName) 1107 if(f)return theName+=type(f)\n return theName\n}\n/* 1108 Add params to the object. Object can be of any type 1109 (normally module or param). 1110 Will be used by modules adding parameters, psets adding parameters.\n*/ 1111 var $LIBasic = $(document.createElement('li')).attr("class","param"); 1112 var $LIExpand = $LIBasic.clone().attr("class","expand");\n 1113 function addParams(obj, params){ 1114 var fileChecked = document.getElementById("ShowFiles").checked 1115 var $span = $(document.createElement("span")); 1116 var $typeSpan = $span.clone().addClass("type"); 1117 var $valSpan = $span.clone().addClass("value"); 1118 var $UL = $(document.createElement("ul")); 1119 var $objName = $(obj).attr('data-name');\n\n if(!params) 1120 params = baseParams($objName)\n for(var i =0; i < params.length; i++){ 1121 var all = params[i].slice() // make copy of it 1122 var isList= typeof(all)=="object" 1123 var theName = isList ? all.shift(): all 1124 var typ= !isList || !all.length ? baseType(theName): all.pop() 1125 var gen = getGenericType(typ) 1126 var spt = $typeSpan.clone().attr("data-name",typ).text(type(typ)) 1127 if(fileChecked) text = getFile(theName) 1128 if(isList && typeof(all[0]) == "object"){\n // PSets 1129 var cloLI = doLI(false,theName,i,"paramInner",spt) 1130 cloLI.attr("data-parent", $objName)\n } 1131 else if(baseParams(theName)){\n // Modules or sequences 1132 var cloLI = doLI(false,theName,i,gen,spt)\n }\n else{ 1133 // Basic type, has no children\n var cloLI= doLI(true,theName,i) 1134 var value =""\n if(all.length)\n var value = all.shift() 1135 // formating so lots of strings look nicer\n var valDataName = value 1136 if(value.indexOf(",")>-1){ 1137 value = "<ul><li>"+value.replace(/,/g, ",</li><li>")+"</li></ul>" 1138 }\n var add = type(typ) 1139 cloLI.append($valSpan.clone().attr("data-name",valDataName).html(value)) 1140 cloLI.append($typeSpan.clone().attr("data-name",add).text(add)) 1141 for(var p=0; p < all.length; p++){\n var n = type(all[p]) 1142 cloLI.append($typeSpan.clone().attr("data-name",n).text(n))\n } 1143 } \n $UL.append(cloLI);\n }\n $(obj).append($UL);\n}\n 1144 function type(theName){\n return " ("+theName+")"\n}\n/* 1145 Helper function: Adds data to a LI.\n*/ 1146 function doLI(basic,dataN,dataI,classes,html){ 1147 if(basic) var $LI = $LIBasic.clone()\n else var $LI = $LIExpand.clone() 1148 $LI.attr("data-name", dataN).attr("data-index", dataI).text(dataN); 1149 if(classes)$LI.addClass(classes)\n if(html)$LI.append(html)\n return $LI 1150 }\n/*\n Box to show params has been clicked.\n*/ 1151 $(document).on('click', '#ShowParams', function(e){ 1152 if($(this).is (':checked')){\n showParams = true\n }\n else{ 1153 $(this).next().hide()\n showParams = false\n }\n});\n/* 1154 Removes children from top level list elements.\n*/ 1155 $(document).on('click', '#hide', function(e){ 1156 //make sure not called when not needed. 1157 if($(this).css('cursor')!='default'){ 1158 var selec = $(".expanded."+topClass).children("ul").hide() 1159 toggleExpand($(".expanded."+topClass ),e)\n invisibleHide()\n }\n}); 1160 // --- end of expand and show more data operations --- 1161 // --- general helper operations and functions ---\n\n/* 1162 Return to normal viewing mode.\n*/\nfunction goNormal(it){ 1163 expandDisable = false; 1164 $(".cellEdit").replaceWith(function() { return $(this).contents();}); 1165 $("#save").remove()\n $("#mode")[0].textContent = "Normal Mode" 1166 it.attr("value", "Edit");\n it.attr("id", "editMode")\n}\n/* 1167 Set what the CURRENT_OBJ is.\n*/\nfunction setCURRENT_OBJ($element){ 1168 var thefunction = $element.attr("data-base"); 1169 var list = $element.attr("data-files").split(" ");\n if(list.length >1){ 1170 CURRENT_OBJ = window[thefunction](list[1], list[0])\n } \n else{ 1171 CURRENT_OBJ = window[thefunction](list[0])\n }\n}\n/* 1172 Add option in html to show/hide parameters.\n*/\nfunction paramOptions(bool){ 1173 if(!bool){\n $("#attachParams").empty()\n return\n } 1174 var lb= jQuery('<label/>', {\n for:"ShowParams"\n }) 1175 jQuery('<input/>', {\n type:"checkbox",\n id:"ShowParams", 1176 name:"ShowParams",\n value:"ShowParams",\n autocomplete:"off" 1177 }).appendTo(lb)\n lb.append("Show Parameters") 1178 lb.appendTo("#attachParams")\n}\n/*\n Small info about each option.\n*/ 1179 $('#showType option').mouseover(function(){ 1180 var docType = $(this).attr("value").toLowerCase();\n var info; 1181 switch(docType){\n case "producer": 1182 info="What's produced by each module."\n break; 1183 case "consumer":\n info="What's consumed by each module." 1184 break;\n default:\n info ="List of "+ docType+"s."\n } 1185 $(this).attr("title", info);\n});\n/*\n Small info about each option.\n*/ 1186 $('span[name="Info"]').mouseover(function(){ 1187 var docType = $(this).attr("value").toLowerCase();\n var info; 1188 switch(docType){\n case "producer": 1189 info="What's produced by each module."\n break; 1190 case "consumer":\n info="What's consumed by each module." 1191 break;\n default:\n info ="List of "+ docType+"s."\n } 1192 $(this).attr("title", info);\n});\n/*\n More info about what's shown.\n*/ 1193 $("#helpMouse").hover(function(e) { 1194 $($(this).data("help")).stop().show(100); 1195 var title = "<h6>(Read the README file!)</h6><h4>Info:</h4> " 1196 var expl = "<h5>Colour codes:</h5> <h6><ul><li class='Path'>pathName"+ 1197 " </li></ul><ul><li class='Modules'>Modules (e.g. "+ 1198 "EDProducer, EDFilter etc)</li></ul><ul><li class='Types'>"+ 1199 "Types (e.g. PSet)</li></ul><ul><li class='param'>"+ 1200 "ParameterName:<span class='value'> value</span><span"+ 1201 " class='type'>(type)</span></li></ul></h6>" 1202 var info ="<h5>The data</h5><h6>The headings you can choose from are"+ 1203 " what was collected from the config file.<br/><br/> Any "+ 1204 "change to the config file means having to run the script "+ 1205 "again and then refresh this page (if same output file was "+ 1207 var tSearch="<h5>Search</h5><h6>Currently can only search by listing "+ 1208 "what items you would like to be searched, and then what part"+ 1209 " of each item.<br/><br/> I.e. search the producers for "+ 1210 "certain names.</h6><br/>" 1211 var problems = "<h5>HTML/JSON/JS issues</h5><h6>If content isn't "+ 1212 "loading,or json files cannot be loaded due to browser"+ 1213 " security issues, try runing the local server created"+ 1214 " by the script. This will be in the same place as "+ 1215 "index.html.<br/><span class='Types'>'python cfgServer.py'"+ 1216 " </span></h6><br/>" 1217 var editing = "<h5>Editing</h5><h6>In order to use the edit mode, you "+ 1218 "need to run the cfgServer.py file, this will be in the "+ 1219 "same directory as the index.html.<br/>Then go to <span"+ 1220 " class='Types'> 'http://localhost:8000/index.html.'"+ 1221 "</span><br/><strong>Please note that the editing of "+ 1222 "SequenceTypes (i.e. Paths, EndPaths etc) and of producers"+ 1223 " and consumers has been " 1224 $($(this).data("help")).html(title+expl+info+problems+editing); 1225 "disabled.</strong></h6><br/>"\n}, function() { 1226 $($(this).data("help")).hide();\n});\n/* 1227 These two functions hide/show the top box in browser.\n*/ 1228 $(document).on('click', '.hideTopBox', function(e){ 1229 $(".topSpec").animate({top: "-2.5em"}, 500);\n $(this).text("show"); 1230 $(this).toggleClass("hideTopBox "+"showTopBox");\n}); 1231 $(document).on('click', '.showTopBox', function(e){ 1232 $(".topSpec").animate({top: "0em"}, 500);\n $(this).text("hide"); 1233 $(this).toggleClass("showTopBox "+ "hideTopBox");\n});\n/* 1234 Stop some links from firing.\n*/\n$('a.nowhere').click(function(e)\n{ 1235 e.preventDefault();\n});\n\n// Turn off any action for clicking help. 1236 $('a#help').bind('click', function() {\n return false;\n});\n/* 1237 If parameter value is a list, hide/show the list on click.\n*/ 1238 $(document).on('click', '.param',function(event){\n if(!expandDisable){ 1239 if($(this).find('ul').length >0){\n $(this).find('ul').toggle();\n }} 1240 event.stopPropagation();\n});\n/* 1241 Removes children from expanded paths or modules.\n*/ 1242 $(document).on('click', '.expanded',function(event){ 1243 var c = $(this).children('ul');\n if(c.length >0){\n $(c).remove(); 1244 }\n event.stopPropagation();\n});\nfunction visibleHide(){ 1245 $('#hide').css('opacity',1);\n $('#hide').css('cursor','pointer'); 1246 hideVisible = true;\n}\nfunction invisibleHide(){ 1247 $('#hide').css('opacity','');\n $('#hide').css('cursor',''); 1248 hideVisible = false;\n}\n\n// Toggles class names. 1249 $(document).on('click','.expand, .expanded', function(event){ 1250 if(!hideVisible && $(this).is('.expand')){\n visibleHide();\n } 1251 toggleExpand(this, event);\n});\n/*\n Helper function toggles class type. 1252 */\nfunction toggleExpand(me,event){\n $(me).toggleClass("expanded expand"); 1253 event.stopPropagation();\n}\n});\n// end of jquery\n/* 1254 Function to load the JSON files.\n*/\nfunction loadJSON(theName){ 1255 return $.ajax({\n type: "GET",\n url: theName, 1256 beforeSend: function(xhr){\n if (xhr.overrideMimeType)\n { 1257 xhr.overrideMimeType("application/json");\n }\n }, 1258 contentType: "application/json",\n async: false,\n dataType: "json" 1259 });\n} \n"""%(pN,pFN))
1263 genericTypes[spec] = generic
1267 return json.dumps(d)
1274 with open(name,
'w')
as f:
1276 #!/usr/bin/env python\nimport SimpleHTTPServer\nimport SocketServer 1277 import shutil\nimport os\nimport cgi\nimport socket\nimport errno\n 1278 #Right now cannot deal with SequenceTypes\nclass CfgConvert: 1279 def __init__(self, obj):\n self._pName = obj["processName"] 1280 self._pFileN = obj["processFileName"]\n obj.__delitem__("processName") 1281 obj.__delitem__("processFileName")\n self._obj = obj 1283 self.header=\"""import FWCore.ParameterSet.Config as cms 1284 process = cms.Process('%(n)s')\nfrom %(fileN)s import *\n%(changes)s\n\n\""" 1285 def _doConversion(self):\n return self.header%( 1286 {"changes":self._doWork(self._obj), 1287 "n":self._pName,"fileN":self._pFileN})\n\n def _doWork(self, obj): 1288 result =""\n for key, value in six.iteritems(obj): 1289 _type = value["Type"]\n _file = value["File"] 1290 _params = value["Parameters"]\n _oType = value["oType"] 1291 if(_oType):\n _oType= "'%s',"%(value["oType"]) 1292 #f = eval(func%(_type))\n if(type(_params)== list): 1293 if(len(_params)==0): 1294 result +="process.%s= cms.%s(%s)\\n"%(key,_type,_oType[:-1]) 1295 else:\n params = self._convert(_params) 1296 result+="process.%s= cms.%s(%s%s)\\n"%(key,_type,_oType, params) 1297 #elif(type(_params)== dict): 1298 # return "Sorry path and endpaths can not currently be translated." 1299 #params = self._doWork(_params)\n 1300 #obj = f("actualType", *parameters)\n return result\n 1301 def _convert(self,params): 1302 # NOTE: params do not take names inside functions 1303 # It is: name = cms.type(value)\n # okay we have a list like 1304 #[name,params, untracked,type]||[name,params,type] 1305 # 2 format options in the params\n # 1. [["name", "value", "type"]] 1306 # 2. [["PsetName",[[as above or this]], "Pset"]]\n 1307 # At position 0 is name. list[0]==name or list[0]==list 1308 # then that will be all 1309 # At position 1 is value or list. list[1]==value||list. 1310 # At position 2 is type. list[2] == type || untracked. 1311 # If there is a position 3 its type. list[3]== type. 1312 if(all(type(x) == list for x in params)): 1313 return ",".join([self._convert(x) for x in params]) 1314 length = len(params)\n if(length==1): 1315 if(type(params[0]) == list):\n # wont have params[1]etc 1316 # do inners\n return self._convert(params[0]) 1317 #wrong format\n print "Error 01 %s"%(str(params))\n return "" 1318 if(length !=3 and length !=4):\n #wrong format 1319 print "Error 02 len is %s"%(str(params))\n return "" 1320 # okay get on with it.\n name = params[0] 1321 if(type(params[1])==list):\n # do listy things 1322 value = self._convert(params[1])\n else:\n value=params[1] 1323 ty = params[2]\n if(name==ty):\n name=""\n if(length==4): 1324 ty+="."+params[3]\n if(name== params[3]):\n name="" 1325 if("vstring" in ty):\n # split the value up by commas 1326 value = ",".join(["'%s'"%x for x in value.split(",")]) 1327 elif("string" in ty):\n #surround string with quotation marks 1328 value = "%s"%(value)\n # okay now done with everything 1329 call= self._func%(ty)\n if(name): 1330 return"%s=%s(%s)"%(name,call,value)\n return"%s(%s)"%(call,value)\n 1331 class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):\n 1332 def do_GET(self):\n if(self.path == "/index.html"): 1333 # find out what cfg html folders we have below 1334 # and add each main html page to the index\n li = os.listdir(".") 1336 dirs = [x for x in li if os.path.isdir(x) and x.endswith(dEnd)] 1338 names = [os.path.join(x,name) for x in dirs if name in os.listdir(x)] 1339 tmpte = '<li><a href ="%(n)s">%(s)s</a></li>' 1340 lis = [tmpte%{"n":x,"s":os.path.split(x)[0].replace(dEnd, "")} 1341 for x in names]\n with open("index.html", 'w') as f: 1342 f.write(\"""\n<!DOCTYPE html>\n<html>\n <head> 1343 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 1344 <title>cfg-browser</title>\n </head>\n <body> 1345 <h4>Configuration files:</h4>\n <ul>\n %s\n </ul>\n </body> 1346 </html>\n \"""%("".join(lis)))\n 1347 return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)\n 1349 ctype,pdict= cgi.parse_header(self.headers.getheader('content-type')) 1350 bdy = cgi.parse_multipart(self.rfile,pdict) 1351 ch= " ".join(bdy[bdy.keys()[0]])\n self.conversion(eval(ch)) 1352 self.writeFile()\n print "finished writing"\n 1353 def conversion(self, json):\n # Need to convert my json into config 1354 result = CfgConvert(json)._doConversion() 1355 with open("changed_cfg.py", 'w')as f:\n f.write(result)\n 1356 def writeFile(self):\n with open("changed_cfg.py", 'rb') as f: 1357 self.send_response(200) 1358 self.send_header("Content-Type", 'text/html') 1359 self.send_header("Content-Disposition", 1360 'attachment; filename="changed_cfg.py"') 1361 fs = os.fstat(f.fileno()) 1362 self.send_header("Content-Length", str(fs.st_size)) 1363 self.end_headers()\n shutil.copyfileobj(f, self.wfile)\n 1364 def main(port=8000, reattempts=5):\n if(port <1024): 1365 print \"""This port number may be refused permission. 1366 It is better to use a port number > 1023.\"""\n try: 1367 Handler = ServerHandler 1368 httpd = SocketServer.TCPServer(("", port), Handler) 1369 print "using port", port 1370 print "Open http://localhost:%s/index.html in your browser."%(port) 1371 httpd.serve_forever()\n except socket.error as e: 1372 if(reattempts >0 and e[0] == errno.EACCES): 1373 print "Permission was denied." 1374 elif(reattempts >0 and e[0]== errno.EADDRINUSE): 1375 print "Address %s is in use."%(port)\n else:\n raise 1376 print "Trying again with a new port number."\n if(port < 1024): 1377 port = 1024\n else:\n port = port +1 1378 main(port, reattempts-1)\n\nif __name__ == "__main__":\n import sys 1379 if(len(sys.argv)>1):\n try:\n port = int(sys.argv[1]) 1380 main(port)\n sys.exit() \n except ValueError: 1381 print "Integer not valid, using default port number."\n main() 1387 if(os.path.isdir(x)):
1389 allItems = os.listdir(x)
1390 py = [os.path.join(x,y)
for y
in allItems
if y.endswith(
".py")]
1396 for y
in os.listdir(x):
1397 path = os.path.join(x,y)
1398 if(os.path.isdir(path)):
1400 for z
in os.listdir(path)]))
1401 elif(x.endswith(
".py")):
1407 def main(args,helperDir,htmlFile,quiet, noServer):
1408 dirName =
"%s-cfghtml" 1416 tmpte =
'<li><a href ="%(n)s">%(s)s</a></li>' 1422 name = os.path.split(x)[1].
replace(
".py",
"")
1423 dirN = dirName%(name)
1431 if not os.path.exists(baseDir):
1432 os.makedirs(baseDir)
1435 lowerHTML = os.path.join(baseDir, htmlFile)
1436 helper = os.path.join(helperDir,
"")
1437 helperdir = os.path.join(baseDir, helper,
"")
1438 if not os.path.exists(helperdir):
1439 os.makedirs(helperdir)
1440 print "Calculating", x
1442 u =
unscheduled(x, lowerHTML, quiet, helper,helperdir)
1443 except Exception
as e:
1444 print "File %s is a config file but something went wrong"%(x)
1447 print "Finished with", x
1448 if(
not u._computed
and dirCreated):
1450 shutil.rmtree(baseDir)
1453 lis += tmpte%{
"n":os.path.join(dirN,htmlFile),
"s":name}
1454 with open(
"index.html",
'w')
as f:
1459 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 1460 <title>cfg-browser</title> 1463 <h4>Configuration files:</h4> 1471 print "Sorry, no configuration files were found." 1473 print "Finished dealing with configuration files." 1477 print "Starting the python server.." 1482 if __name__ ==
"__main__":
1483 import sys, os, imp, shutil
1484 from optparse
import OptionParser
1485 parser = OptionParser(usage=
"%prog <cfg-file> ")
1486 parser.add_option(
"-q",
"--quiet",
1487 action=
"store_true", dest=
"_quiet", default=
False,
1488 help=
"Print minimal messages to stdout")
1491 parser.add_option(
"-s",
"--no_server",
1492 action=
"store_true", dest=
"_server", default=
False,
1493 help=
"Disable starting a python server to view "\
1494 "the html after finishing with config files.")
1495 parser.add_option(
"-r",
"--recurse", dest=
"_recurse",action=
"store_true",
1497 help=
"Search directories recursively for .py files.")
1500 helper_dir =
"cfgViewerJS" 1501 opts, args = parser.parse_args()
1504 distBaseDirectory=os.path.abspath(
1505 os.path.join(os.path.dirname(__file__),
".."))
1506 if (
not os.path.exists(distBaseDirectory)
or 1507 not "Vispa" in os.listdir(distBaseDirectory)):
1508 distBaseDirectory=os.path.abspath(
1509 os.path.join(os.path.dirname(__file__),
"../python"))
1510 if (
not os.path.exists(distBaseDirectory)
or 1511 not "Vispa" in os.listdir(distBaseDirectory)):
1512 distBaseDirectory=os.path.abspath(os.path.expandvars(
1513 "$CMSSW_BASE/python/FWCore/GuiBrowsers"))
1514 if (
not os.path.exists(distBaseDirectory)
or 1515 not "Vispa" in os.listdir(distBaseDirectory)):
1516 distBaseDirectory=os.path.abspath(os.path.expandvars(
1517 "$CMSSW_RELEASE_BASE/python/FWCore/GuiBrowsers"))
1519 distBaseDirectory=os.path.abspath(
1520 os.path.join(os.path.dirname(sys.argv[0]),
".."))
1521 sys.path.insert(0,distBaseDirectory)
1523 distBinaryBaseDirectory=os.path.join(baseDirectory,
"dist")
1524 sys.path.append(distBinaryBaseDirectory)
1525 from FWCore.GuiBrowsers.Vispa.Plugins.ConfigEditor
import ConfigDataAccessor
1527 recurse = opts._recurse
1528 doesNotExist = [x
for x
in args
if not os.path.exists(x)]
1529 if(len(doesNotExist)):
1531 for x
in doesNotExist:
1533 s +=
"%s does not exist.\n"%(x)
1536 if(len(args)==0
or len(doesNotExist)== len(args)):
1538 Either you provided no arguments, or the arguments provided do not exist. 1540 If you need help finding files, provide arguments "." -r and I will search 1541 recursively through the directories in the current directory. 1544 main(args,
"cfgViewerJS",
"main.html",opts._quiet, opts._server)
def getParameters(parameters)
def _mothersDaughters(self, name, item)
def __init__(self, df, cfg)
def main(args, helperDir, htmlFile, quiet, noServer)
def _doSequenceTypes(self, paths, namep)
def replace(string, replacements)
def _css(self, css, cssLocal)
def _writeProdConsum(self)
def __init__(self, cfgFile, html, quiet, helperDir, fullDir)
def _searchitems(self, items)
def _jqueryFile(self, name, pN, pFN)
def _doModules(self, modObj, dataFile, seq, seqs, currentName, innerSeq)
def _saveData(self, name, base, jsonfiles)
def _filenames(self, name, option="")
def __init__(self, name, js, items, theDir, helperDir, pN, pFN)
def _doNonSequenceType(self, objs, globalType)
def getParamSeqDict(params, fil, typ, oType)
static std::string join(char **cmd)
def _calcFilenames(self, name)
def _printHtml(self, name, scrip, css, items, search)
def _complexBase(self, parentName, extra)
def doTypes(spec, generic)
def printServer(self, name)
def _checkType(self, item)
def _load(self, name, param, inner)
def _writeModSeqParent(self)
def _writeDictParent(self, typeName)
def _proceed(self, fileName)
def _producersConsumers(self)