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