Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:37

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 ## MainPageGenerator class is used for generating main page that contains domain trees (Analysis, Calibration and Alignment, Core, DAQ etc.) 
0007 class MainPageGenerator:
0008     ## Constructor method.
0009     # @param dataPath parameter gives path of data directory that contains .js, .css and image files needed for generating tree pages
0010     # @param path is the reference manual directory path and it is used as destination and source.
0011     # @param cmsVer is version of CMSSW.
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)          #backup file
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('&lt;','<').replace('&gt;', '>')
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 # 1 for doxygen 1.8.5, 2 for old ver.
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         # for getting package links
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         # for getting items from file.html
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         # depth of interface items can be only 3
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 #            print i.text, self.__GetHTMLItemDepth(i)
0224 #            raw_input()
0225             
0226             if flag and i.text != u'interface':
0227                 self.classes[level1][level2][i.text] = i.a["href"]
0228                 #self.ZEG = i
0229         print("Class hierarchy loaded(%d)..." % len(self.classes))
0230         
0231 #        self.WriteFile("dbg.json", json.dumps(self.classes, indent = 1))
0232         
0233         # for parsing classes links from classes.html
0234         soup        = BeautifulSoup(self.classesSource)
0235         contents    = soup.find("div", { "class" : "contents" })
0236         td          = contents.findAll("td", {})
0237         self.classesURLs = {}
0238         # add items to self.classesURLs
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&amp;cvsroot=CMSSW&amp;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&amp;cvsroot=CMSSW&amp;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&amp;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> &gt; cmsrel CMSSW_7_X_X
0285          &gt; cd CMSSW_7_X_X/
0286          &gt; cmsenv
0287          &gt; git cms-addpkg Documentation
0288 
0289          &gt; generate_reference_manual
0290 
0291          wait...
0292 
0293          &gt; 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'    ######### TAG: TR1
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'               ######### TAG: TR1
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 #                if len(self.data[domain][i][j].keys()) == 1:
0355 #                    if self.data[domain][i][j].has_key("__DATA__"):
0356 #                        content += self.HTMLTreeAddItem(j, self.data[domain][i][j]["__DATA__"])
0357 #                    else:
0358 #                        content += self.HTMLTreeAddItem(j)
0359 #                    continue
0360                 keysK = sorted(self.data[domain][i][j].keys())
0361                 length = len(keysK)
0362 #                content += "<!-- Begin -->"
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 #                content += "<!-- End -->"
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     #os.system("cp -rf %s../data/iframes/ %s" % (os.path.split(__file__)[0], PATH))
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")