Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:11

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