File indexing completed on 2023-03-17 10:51:56
0001 from __future__ import print_function
0002 from __future__ import absolute_import
0003 import json, urllib2, os, sys
0004 from bs4 import BeautifulSoup
0005
0006
0007 class MainPageGenerator:
0008
0009
0010
0011
0012 def __init__(self, dataPath, path, cmsVer = ""):
0013 self.path = path
0014 self.dataPath = dataPath
0015
0016 self.CMSVER = cmsVer
0017
0018 self.managersURL = 'http://cmsdoxy.web.cern.ch/cmsdoxy/tcproxy.php?type=managers'
0019 self.usersURL = 'http://cmsdoxy.web.cern.ch/cmsdoxy/tcproxy.php?type=users'
0020 self.CMSSWURL = 'http://cmsdoxy.web.cern.ch/cmsdoxy/tcproxy.php?type=packages&release=CMSSW_4_4_2'
0021
0022 self.tWikiLinks = {'Analysis':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideCrab',
0023 'Calibration and Alignment':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideCalAli',
0024 'Core':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideFrameWork',
0025 'DAQ':'https://twiki.cern.ch/twiki/bin/view/CMS/TriDASWikiHome',
0026 'DQM':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideDQM',
0027 'Database':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideCondDB',
0028 'Documentation':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuide',
0029 'Fast Simulation':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideFastSimulation',
0030 'Full Simulation':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideSimulation',
0031 'Generators':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideEventGeneration',
0032 'Geometry':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideDetectorDescription',
0033 'HLT':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideHighLevelTrigger',
0034 'L1':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideL1Trigger',
0035 'Reconstruction':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideReco',
0036 'Visualization':'https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideVisualization'}
0037
0038 self.data = None
0039
0040 self.GitLink = "https://github.com/cms-sw/cmssw/tree/" + self.CMSVER + "/%s/%s"
0041
0042 self.title = "<center>\n<h1>CMSSW Documentation</h1>\n<h2>" + self.CMSVER + "</h2>\n</center>\n"
0043 self.links = """
0044 <p style="margin-left:10px;">
0045 Learn <a href="ReferenceManual.html">how to build Reference Manual</a><br>
0046 Learn more about <a target="_blank" href="http://www.stack.nl/~dimitri/doxygen/commands.html">special doxygen commands</a>
0047 </p>\n\n"""
0048 self.head = """
0049 <!-- Content Script & Style -->
0050 <script type="text/javascript">
0051 var itemList = [];
0052
0053 function toggleHoba(item, path)
0054 {
0055 for(var i = 0; i < itemList.length; i++)
0056 {
0057 if(itemList[i] == item)
0058 {
0059 var iframe = $("#"+itemList[i]+"_div").children("iframe:first");
0060 if(!iframe.attr("src"))
0061 {
0062 iframe.attr("src", path)
0063 }
0064 $("#"+item+"_div").slideToggle();
0065 }
0066 else
0067 $("#"+itemList[i]+"_div").slideUp();
0068 }
0069 }
0070
0071 $(document).ready(function() {
0072 searchBox.OnSelectItem(0);
0073 $(".doctable").find("td").each(function(){ if (this.id.indexOf("hoba_") != -1)itemList.push(this.id);});
0074 });
0075 </script>
0076 <style>
0077 .DCRow
0078 {
0079 background: #eeeeff;
0080 border-spacing: 0px;
0081 padding: 0px;
0082 border-bottom: 1px solid #c1c1dc;
0083 }
0084
0085 .DCRow:hover
0086 {
0087 background: #cde4ec;
0088 }
0089 </style>
0090 <!-- Content Script & Style -->
0091 """
0092 self.contentStamp = '$CONTENT$'
0093 self.mainPageTemplate = self.ReadFile("index.html")
0094 self.WriteFile("index_backup.html", self.mainPageTemplate)
0095 soup = BeautifulSoup(self.mainPageTemplate)
0096 soup.head.insert(len(soup.head), self.head)
0097
0098 contents = soup.find("div", { "class" : "contents" })
0099 for child in contents.findChildren():
0100 child.extract()
0101 contents.insert(0, self.contentStamp)
0102 self.mainPageTemplate = str(soup)
0103 self.mainPageTemplate = self.mainPageTemplate.replace("CSCDQM Framework Guide", "")
0104 self.mainPageTemplate = self.mainPageTemplate.replace('<','<').replace('>', '>')
0105 print("Main page template created...")
0106
0107 self.CreateBuildRefMan()
0108 print("RefMan created...")
0109
0110 self.treePageTamplate = self.ReadFile(self.dataPath + "tree_template.html", pathFlag = False)
0111 self.classesSource = self.ReadFile("classes.html")
0112 self.filesSource = self.ReadFile("files.html")
0113 self.packageSource = self.ReadFile("pages.html")
0114
0115 def ReadFile(self, fileName, pathFlag = True):
0116 """This method reads file directly or from path."""
0117 if pathFlag:
0118 print("Read:", self.path + fileName)
0119 f = open(self.path + fileName)
0120 else:
0121 f = open(fileName)
0122 print("Read:", fileName)
0123 data = f.read()
0124 f.close()
0125 return data
0126
0127 def WriteFile(self, fileName, data):
0128 """This method writes data"""
0129 print("Write:", self.path + fileName)
0130 f = open(self.path + fileName, "w")
0131 f.write(data)
0132 f.close()
0133
0134 def GetFileName(self, fileName):
0135 """This method returns file name without extension"""
0136 if '.' in fileName:
0137 return fileName[0:fileName.find('.')]
0138 else:
0139 return fileName
0140
0141 def ParseJsonFromURL(self, URL):
0142 """This method returns data which is read from URL"""
0143 u = urllib2.urlopen(URL)
0144 return json.loads(u.read())
0145
0146 def __ParseItem(self, str_):
0147 return str_[0:str_.find('/')]
0148
0149 def __ParseSubItem(self, str_):
0150 if '/' in str_:
0151 return str_[str_.find('/')+1:]
0152 else:
0153 return None
0154
0155 def __GetHTMLItemDepth(self, item):
0156 return item["id"].count("_") - 1
0157
0158 def __HTMLFileName(self, fileName):
0159 return fileName.lower().replace(' ', '_')
0160
0161 def PrepareData(self):
0162 self.managers = self.ParseJsonFromURL(self.managersURL)
0163 print("Managers loaded and parsed...")
0164
0165 self.users = self.ParseJsonFromURL(self.usersURL)
0166 print("Users loaded and parsed...")
0167
0168 self.data = {}
0169 for i in self.managers.keys():
0170 self.data[i] = {"__DATA__":{"Contact":[]}}
0171 for j in self.managers[i]:
0172 self.data[i]["__DATA__"]["Contact"].append(self.users[j])
0173 self.domains = self.ParseJsonFromURL(self.CMSSWURL)
0174 print("Domains loaded and parsed...")
0175
0176 for i in self.domains.keys():
0177 for j in self.domains[i]:
0178 if self.__ParseItem(j) not in self.data[i]:
0179 self.data[i][self.__ParseItem(j)] = {}
0180 if self.__ParseSubItem(j) not in self.data[i][self.__ParseItem(j)]:
0181 self.data[i][self.__ParseItem(j)][self.__ParseSubItem(j)] = {}
0182
0183 self.data[i][self.__ParseItem(j)][self.__ParseSubItem(j)]["__DATA__"] = {
0184 'git': self.GitLink % (self.__ParseItem(j), self.__ParseSubItem(j))
0185 }
0186
0187
0188 soup = BeautifulSoup(self.packageSource)
0189 contents = soup.find("div", { "class" : "contents" })
0190 li = contents.findAll("tr", {})
0191
0192 self.packages = {}
0193 for i in li:
0194 if i.a["href"]:
0195 self.packages[i.a.text] = i.a["href"]
0196 print("Packages parsed(%d)..." % len(self.packages))
0197
0198
0199 soup = BeautifulSoup(self.filesSource)
0200 contents = soup.find("div", { "class" : "contents" })
0201 tr = contents.findAll("tr", {})
0202 self.classes= {}
0203 origin = 0
0204 if tr[0].text == 'src': origin = -1
0205
0206 flag = False
0207 for i in tr:
0208 if self.__GetHTMLItemDepth(i) + origin == 1:
0209 self.classes[i.text] = {}
0210 level1 = i.text
0211 flag = False
0212
0213 if self.__GetHTMLItemDepth(i) + origin == 2:
0214 self.classes[level1][i.text] = {}
0215 level2 = i.text
0216 flag = False
0217
0218 if self.__GetHTMLItemDepth(i) + origin == 3 and i.text == u'interface':
0219 flag = True
0220 if self.__GetHTMLItemDepth(i) + origin == 3 and i.text != u'interface':
0221 flag = False
0222
0223
0224
0225
0226 if flag and i.text != u'interface':
0227 self.classes[level1][level2][i.text] = i.a["href"]
0228
0229 print("Class hierarchy loaded(%d)..." % len(self.classes))
0230
0231
0232
0233
0234 soup = BeautifulSoup(self.classesSource)
0235 contents = soup.find("div", { "class" : "contents" })
0236 td = contents.findAll("td", {})
0237 self.classesURLs = {}
0238
0239 for i in td:
0240 if i.a and 'href' in i.a:
0241 self.classesURLs[i.a.text] = i.a['href']
0242 print("Class URLs was loaded... (%s)" % len(self.classesURLs))
0243
0244 for i in self.data.keys():
0245 for j in self.data[i].keys():
0246 if j not in self.classes: continue
0247 for k in self.data[i][j].keys():
0248 if "Package " + j + "/" + k in self.packages:
0249 self.data[i][j][k]["__DATA__"]["packageDoc"] = '../' + self.packages["Package " + j + "/" + k]
0250 if k not in self.classes[j]: continue
0251 for h in self.classes[j][k]:
0252 if self.GetFileName(h) in self.classesURLs:
0253 self.data[i][j][k][self.GetFileName(h)] = {"__DATA__": '../' + self.classesURLs[self.GetFileName(h)]}
0254 else:
0255 self.data[i][j][k][self.GetFileName(h) + ".h"] = {"__DATA__": '../' + self.classes[j][k][h]}
0256
0257 def ExportJSON(self, fileName):
0258 if self.data == None:
0259 self.PrepareData()
0260 self.WriteFile(fileName, json.dumps(self.data, indent = 1))
0261
0262 def CreateBuildRefMan(self):
0263 content = """<h1>The Reference Manual </h1>
0264 This is the CMSSW Reference Manual, the reference documentation of all classes and packages in CMSSW.<p>
0265 This page explains how to write the documentation for your code.
0266
0267 </p><h2>Class Documentation</h2>
0268
0269 Classes and methods are documented with properly formatted <a target="_blank" class="el" href="d3/d88/namespacecomments.html">comments</a> in the code.<p>
0270 Here is a template of a documented <a target="_blank" href="http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/Documentation/CodingRules/Template.h?rev=HEAD&cvsroot=CMSSW&content-type=text/vnd.viewcvs-markup">.h file</a>, and of a <a target="_blank" href="http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/Documentation/CodingRules/Template.cc?rev=HEAD&cvsroot=CMSSW&content-type=text/vnd.viewcvs-markup">.cc file</a>. The resulting doxygen page is <a target="_blank" class="el" href="d6/d3e/classTemplate.html">here</a>.
0271
0272 </p><h2>Package Documentation</h2>
0273
0274 Each package should contain a very brief description of its content and purpose. Remember that this is a reference, and not a user's guide: tutorials, howtos, etc. are best documented in the <a target="_blank" href="https://twiki.cern.ch/twiki/bin/view/CMS/SWGuide">CMS Offline Guide</a> and in the <a target="_blank" href="https://twiki.cern.ch/twiki/bin/view/CMS/WorkBook">WorkBook</a>. Cross links between the CMS Offline Guide and the WorkBook and this manual are a good way to avoid duplication of content.<p>
0275 This documentation should be written in a file [Package]/doc/[Package].doc. The simplest way of doing this is to go to the doc/ directory in your package and then run the script
0276 <a target="_blank" href="http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/*checkout*/CMSSW/Documentation/ReferenceManualScripts/scripts/makePackageDoc?rev=HEAD&cvsroot=CMSSW">makePackageDoc</a>,
0277 which is available in your PATH.
0278
0279 </p><h2> How to generate your documentation locally </h2>
0280 One you have updated your documentation, you can look at how it displays in the following way:
0281
0282 <ul>
0283 <li>check out the following packages:
0284 <pre> > cmsrel CMSSW_7_X_X
0285 > cd CMSSW_7_X_X/
0286 > cmsenv
0287 > git cms-addpkg Documentation
0288
0289 > generate_reference_manual
0290
0291 wait...
0292
0293 > firefox doc/html/index.html </pre>
0294 </li>
0295 </ul>"""
0296 self.WriteFile('ReferenceManual.html', self.mainPageTemplate.replace(self.contentStamp, content))
0297
0298 def CreateNewMainPage(self, outputFileName):
0299 if self.data == None:
0300 self.PrepareData()
0301
0302 contents = """
0303 <table class="doctable" border="0" cellpadding="0" cellspacing="0">
0304 <tbody>
0305 <tr class="top" valign="top">
0306 <th class="domain">Domain</th><th class="contact">Contact</th>
0307 </tr>
0308 """
0309 keysI = sorted(self.data.keys())
0310 for i in keysI:
0311
0312 if i == 'Other': continue
0313
0314 self.__NewTreePage(i)
0315 contents = contents + '\n<tr class="DCRow">\n'
0316
0317 if i == 'Operations':
0318 contents = contents + """<td width="50%%" style="padding:8px">%s</td>\n""" % i
0319 else:
0320 contents = contents + """<td width="50%%" style="padding:8px;cursor:pointer" onclick="toggleHoba('hoba_%s', 'iframes/%s.html')" id="hoba_%s"><a>%s</a></td>\n""" % (i.replace(' ', '_'), i.lower().replace(' ', '_'), i.replace(' ', '_'), i)
0321
0322
0323 contents = contents + '<td width="50%" class="contact">'
0324 for j in range(len(self.data[i]["__DATA__"]["Contact"])):
0325 if j == len(self.data[i]["__DATA__"]["Contact"]) - 1:
0326 contents = contents + '<a href="mailto:%s">%s</a> ' % (self.data[i]["__DATA__"]["Contact"][j][1], self.data[i]["__DATA__"]["Contact"][j][0])
0327 else:
0328 contents = contents + '<a href="mailto:%s">%s</a>, ' % (self.data[i]["__DATA__"]["Contact"][j][1], self.data[i]["__DATA__"]["Contact"][j][0])
0329 contents = contents + '</td>\n'
0330 contents = contents + '</tr>\n\n'
0331
0332 if i == 'Operations': continue
0333
0334 contents = contents + """
0335 <tr><td colspan="2" style="background:#d7dbe3">
0336 <div style="display:none;" id="hoba_%s_div"><iframe width="100%%" frameborder="0"></iframe></div>
0337 </td></tr>
0338 """ % (i.replace(' ', '_'))
0339
0340 contents = contents + "</table>"
0341 self.WriteFile(outputFileName, self.mainPageTemplate.replace(self.contentStamp, self.title + contents + self.links))
0342
0343 def __NewTreePage(self, domain):
0344
0345 if domain not in self.data: return
0346
0347 content = ''
0348 keysI = sorted(self.data[domain].keys())
0349 for i in keysI:
0350 if i == '__DATA__': continue
0351 content += self.HTMLTreeBegin(i)
0352 keysJ = sorted(self.data[domain][i].keys())
0353 for j in keysJ:
0354
0355
0356
0357
0358
0359
0360 keysK = sorted(self.data[domain][i][j].keys())
0361 length = len(keysK)
0362
0363 if length > 1:
0364 if "__DATA__" in self.data[domain][i][j]:
0365 content += self.HTMLTreeBegin(j, self.data[domain][i][j]["__DATA__"])
0366 else:
0367 content += self.HTMLTreeBegin(j)
0368 else:
0369 if "__DATA__" in self.data[domain][i][j]:
0370 content += self.HTMLTreeAddItem(j, self.data[domain][i][j]["__DATA__"], folder = True)
0371 else:
0372 content += self.HTMLTreeAddItem(j, folder = True)
0373
0374 for k in keysK:
0375 if k == '__DATA__': continue
0376 if self.data[domain][i][j][k]["__DATA__"]: content += self.HTMLTreeAddItem(k, self.data[domain][i][j][k]["__DATA__"])
0377 else: content += self.HTMLTreeAddItem(k)
0378 if length > 1:
0379 content += self.HTMLTreeEnd()
0380
0381 content += self.HTMLTreeEnd()
0382 if domain in self.tWikiLinks:
0383 self.WriteFile("iframes/%s.html" % domain.lower().replace(' ', '_'), self.treePageTamplate % (domain, self.tWikiLinks[domain], content))
0384 else:
0385 print('Warning: The twiki link of "%s" domain not found...' % domain)
0386 self.WriteFile("iframes/%s.html" % domain.lower().replace(' ', '_'), self.treePageTamplate % (domain, '#', content))
0387
0388 def HTMLTreeBegin(self, title, links = {}):
0389 html = '\n<li>\n<div class="hitarea expandable-hitarea"></div>\n'
0390 html = html + '<span class="folder">%s\n' % title
0391 for i in links.keys():
0392 html = html + '<a target="_blank" href="%s">[%s]</a> \n' % (links[i], i)
0393 html = html + '</span>\n'
0394 html = html + '<ul style="display: block;">\n'
0395 return html
0396
0397 def HTMLTreeEnd(self):
0398 return '</li></ul>\n\n'
0399
0400 def HTMLTreeAddItem(self, title, links = None, endNode = False, folder = False):
0401 if endNode: html = '\t<li class="last">'
0402 else: html = '\t<li>'
0403
0404 if isinstance(links, str) or isinstance(links, type(u'')):
0405 if folder:
0406 html = html + '\t<a href="%s" target="_blank" class=""><span class="emptyFolder">%s</span></a>\n' % (links, title)
0407 else:
0408 html = html + '\t<a href="%s" target="_blank" class=""><span class="file">%s</span></a>\n' % (links, title)
0409 elif isinstance(links, dict):
0410 if folder:
0411 html = html + '<span class="emptyFolder">%s ' % title
0412 else:
0413 html = html + '<span class="file">%s ' % title
0414 for i in links.keys():
0415 html = html + '<a target="_blank" href="%s">[%s]</a> \n' % (links[i], i)
0416 html = html + '</span>'
0417 else:
0418 html = html + '\t<span class="file">%s</span>\n' % title
0419 return html + '\t</li>\n'
0420
0421 if len(sys.argv) == 5:
0422 DATA_PATH = sys.argv[1]
0423 PATH = sys.argv[2]
0424 VER = sys.argv[3]
0425 OUTF = sys.argv[4]
0426
0427
0428
0429 l = MainPageGenerator(DATA_PATH, PATH, cmsVer = VER)
0430
0431 l.CreateNewMainPage(OUTF)
0432 else:
0433 print("parameter error. It must be like this: python MainPageGenerator.py DATA_PATH/ CMSSW/doc/html/ CMS_VER OUTPUT_FILE_NAME")