Module EdnaPluginList
[hide private]
[frames] | no frames]

Source Code for Module EdnaPluginList

  1  #!/usr/bin/env python 
  2  #-*- coding: UTF8 -*- 
  3  # 
  4  #    Project: The EDNA Kernel 
  5  #             http://www.edna-site.org 
  6  # 
  7  #    File: "$Id: EdnaPluginList.py $" 
  8  # 
  9  #    Copyright (C) 2008-2011 European Synchrotron Radiation Facility 
 10  #                            Grenoble, France 
 11  # 
 12  # 
 13  #    This program is free software: you can redistribute it and/or modify 
 14  #    it under the terms of the GNU Lesser General Public License as published 
 15  #    by the Free Software Foundation, either version 3 of the License, or 
 16  #    (at your option) any later version. 
 17  # 
 18  #    This program is distributed in the hope that it will be useful, 
 19  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 20  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 21  #    GNU Lesser General Public License for more details. 
 22  # 
 23  #    You should have received a copy of the GNU General Public License 
 24  #    and the GNU Lesser General Public License  along with this program.   
 25  #    If not, see <http://www.gnu.org/licenses/>. 
 26  # 
 27  """ 
 28  This is a generator retrieving all plugin (by their name) and retrieve some basic statisitcs    
 29  """ 
 30   
 31  __authors__ = ["Jérôme Kieffer", "Régis Perdreau"] 
 32  __contact__ = "Jerome.Kieffer@esrf.eu" 
 33  __license__ = "GPLv3" 
 34  __date__ = "2011-05-20" 
 35  __copyright__ = "ESRF" 
 36   
 37  import os, sys, shutil, stat, time 
 38   
 39   
 40  if "EDNA_HOME" not in os.environ: 
 41      strEdnaHome = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 
 42      os.environ["EDNA_HOME"] = strEdnaHome 
 43  else: 
 44      strEdnaHome = os.environ["EDNA_HOME"] 
45 46 -def getPlugins(strPath, htmlpath=None):
47 """ 48 @return: a dict with key=plugin and value=path 49 """ 50 dictPlugins = {} 51 dictProject = {} 52 iControlPl = 0 53 iExecPl = 0 54 iOtherPl = 0 55 ilen = len(strPath) + 1 56 for root, dirs, files in os.walk(strPath, topdown=False): 57 for name in files: 58 if name.startswith("EDPlugin") and name.endswith(".py"): 59 strPlugin = name[:-3] 60 plugin = EdnaPlugin(os.path.join(root, name)[ilen:]) 61 dictPlugins[strPlugin] = plugin 62 plugin.analyse() 63 project = plugin.project 64 strType = plugin.type 65 if htmlpath is not None: 66 html = plugin.getHtml() 67 open(os.path.join(htmlpath, strPlugin + ".html"), "w").write(html) 68 69 if strType == "Control Plugins": 70 iControlPl += 1 71 elif strType == "Execution Plugins": 72 iExecPl += 1 73 else: 74 iOtherPl += 1 75 if project in dictProject: 76 if strType in dictProject[project]: 77 dictProject[project][strType][strPlugin] = plugin 78 else: 79 dictProject[project][strType] = {strPlugin:plugin} 80 else: 81 dictProject[project] = {strType:{strPlugin:plugin}} 82 return dictProject, {"Control":iControlPl, "Execution":iExecPl, "Others": iOtherPl}
83
84 85 -def prettyPrint(dictProjects, dictNumbers):
86 """ 87 @type dictProjects: dict 88 @type dictNumbers: dict 89 @return: a string 90 """ 91 lstStr = [] 92 for i in dictNumbers: 93 lstStr += ["Number of %s Plugins:\t%d" % (i, dictNumbers[i])] 94 lstProjects = dictProjects.keys() 95 lstProjects.sort() 96 for project in lstProjects: 97 lstStr.append(project) 98 lstType = dictProjects[project].keys() 99 lstType.sort() 100 for strType in lstType: 101 lstStr.append("\t%s" % strType) 102 lstPlugins = dictProjects[project][strType].keys() 103 lstPlugins.sort() 104 for strPlugin in lstPlugins: 105 lstStr.append("\t\t%s:\t%s" % (strPlugin, os.linesep.join(dictProjects[project][strType][strPlugin].classDoc))) 106 lstStr.append("") 107 return os.linesep.join(lstStr)
108
109 110 -def prettyHtml(dictProjects, dictNumbers):
111 """ 112 @return: a string 113 """ 114 lstStr = ["<html>", "<head>", "<title>List of EDNA Plugins</title>", "</head>", \ 115 "<body>", "<center><h1>List of EDNA Plugins</h1></center>", "<table>", \ 116 "<tr><td>Generated on:</td><td>%s</td></tr>" % (time.asctime())] 117 for i in dictNumbers: 118 lstStr += ["<tr><td>Number of %s Plugins:</td><td>%d</td></tr>" % (i, dictNumbers[i])] 119 lstStr += ["</table><hr>"] 120 lstProjects = dictProjects.keys() 121 lstProjects.sort() 122 for project in lstProjects: 123 lstStr.append("<h2>%s<h2>" % project) 124 lstType = dictProjects[project].keys() 125 lstType.sort() 126 for strType in lstType: 127 lstStr.append("<h3>%s<h3>" % strType) 128 lstPlugins = dictProjects[project][strType].keys() 129 lstPlugins.sort() 130 lstStr.append("<table>") 131 for strPlugin in lstPlugins: 132 plugin = dictProjects[project][strType][strPlugin] 133 for datamodel in plugin.datamodel: 134 for datamodelImg in plugin.dictXSD: 135 if (plugin.datamodel[datamodel] is not None) and \ 136 datamodelImg.startswith(plugin.datamodel[datamodel]) and \ 137 plugin.dictXSD[datamodelImg].endswith(".png"): 138 destDatamodel = os.path.join(strDest, datamodelImg + ".png") 139 if os.path.isfile(destDatamodel) and os.path.isfile(plugin.dictXSD[datamodelImg]): 140 os.remove(destDatamodel) 141 try: 142 shutil.copy(plugin.dictXSD[datamodelImg], destDatamodel) 143 except shutil.Error: 144 print("Unable to copy %s to %s" % (plugin.dictXSD[plugin.datamodel], destDatamodel)) 145 except IOError: 146 print("Unable to find Datamodel Image %s" % (plugin.dictXSD[datamodelImg])) 147 lstStr.append("<tr><td><a href='%s'>%s</a></td><td>%s</td></tr>" % 148 (os.path.join(os.path.basename(strDest), strPlugin + ".html"), strPlugin, 149 "<br>".join([unicode2html(i) for i in plugin.classDoc]))) 150 151 lstStr.append("</table>") 152 lstStr.append("<hr>") 153 lstStr.append("</body></html>") 154 return os.linesep.join(lstStr)
155
156 -def unicode2html(_unicodeIn):
157 """ 158 Converts an unicode input into a "html" like string 159 160 @param _unicodeIn: input unicode 161 @return: html string 162 """ 163 dico = {u'\u0022': '&quot;', u'\u0026': '&amp;', u'\u0027': '&apos;', u'\u003C': '&lt;', u'\u003E': '&gt;', u'\u00A0': '&nbsp;', u'\u00A1': '&iexcl;', u'\u00A2': '&cent;', 164 u'\u00A3': '&pound;', u'\u00A4': '&curren;', u'\u00A5': '&yen;', u'\u00A6': '&brvbar;', u'\u00A7': '&sect;', u'\u00A8': '&uml;', u'\u00A9': '&copy;', u'\u00AA': '&ordf;', 165 u'\u00AB': '&laquo;', u'\u00AC': '&not;', u'\u00AD': '&shy;', u'\u00AE': '&reg;', u'\u00AF': '&macr;', u'\u00B0': '&deg;', u'\u00B1': '&plusmn;', u'\u00B2': '&sup2;', 166 u'\u00B3': '&sup3;', u'\u00B4': '&acute;', u'\u00B5': '&micro;', u'\u00B6': '&para;', u'\u00B7': '&middot;', u'\u00B8': '&cedil;', u'\u00B9': '&sup1;', u'\u00BA': '&ordm;', 167 u'\u00BB': '&raquo;', u'\u00BC': '&frac14;', u'\u00BD': '&frac12;', u'\u00BE': '&frac34;', u'\u00BF': '&iquest;', u'\u00C0': '&Agrave;', u'\u00C1': '&Aacute;', u'\u00C2': '&Acirc;', 168 u'\u00C3': '&Atilde;', u'\u00C4': '&Auml;', u'\u00C5': '&Aring;', u'\u00C6': '&AElig;', u'\u00C7': '&Ccedil;', u'\u00C8': '&Egrave;', u'\u00C9': '&Eacute;', u'\u00CA': '&Ecirc;', 169 u'\u00CB': '&Euml;', u'\u00CC': '&Igrave;', u'\u00CD': '&Iacute;', u'\u00CE': '&Icirc;', u'\u00CF': '&Iuml;', u'\u00D0': '&ETH;', u'\u00D1': '&Ntilde;', u'\u00D2': '&Ograve;', 170 u'\u00D3': '&Oacute;', u'\u00D4': '&Ocirc;', u'\u00D5': '&Otilde;', u'\u00D6': '&Ouml;', u'\u00D7': '&times;', u'\u00D8': '&Oslash;', u'\u00D9': '&Ugrave;', u'\u00DA': '&Uacute;', 171 u'\u00DB': '&Ucirc;', u'\u00DC': '&Uuml;', u'\u00DD': '&Yacute;', u'\u00DE': '&THORN;', u'\u00DF': '&szlig;', u'\u00E0': '&agrave;', u'\u00E1': '&aacute;', u'\u00E2': '&acirc;', 172 u'\u00E3': '&atilde;', u'\u00E4': '&auml;', u'\u00E5': '&aring;', u'\u00E6': '&aelig;', u'\u00E7': '&ccedil;', u'\u00E8': '&egrave;', u'\u00E9': '&eacute;', u'\u00EA': '&ecirc;', 173 u'\u00EB': '&euml;', u'\u00EC': '&igrave;', u'\u00ED': '&iacute;', u'\u00EE': '&icirc;', u'\u00EF': '&iuml;', u'\u00F0': '&eth;', u'\u00F1': '&ntilde;', u'\u00F2': '&ograve;', 174 u'\u00F3': '&oacute;', u'\u00F4': '&ocirc;', u'\u00F5': '&otilde;', u'\u00F6': '&ouml;', u'\u00F7': '&divide;', u'\u00F8': '&oslash;', u'\u00F9': '&ugrave;', u'\u00FA': '&uacute;', 175 u'\u00FB': '&ucirc;', u'\u00FC': '&uuml;', u'\u00FD': '&yacute;', u'\u00FE': '&thorn;', u'\u00FF': '&yuml;', u'\u0152': '&OElig;', u'\u0153': '&oelig;', 176 u'\u0160': '&Scaron;', u'\u0161': '&scaron;', u'\u0178': '&Yuml;', u'\u0192': '&fnof;', u'\u02C6': '&circ;', u'\u02DC': '&tilde;', 177 u'\u0391': '&Alpha;', u'\u0392': '&Beta;', u'\u0393': '&Gamma;', u'\u0394': '&Delta;', u'\u0395': '&Epsilon;', 178 u'\u0396': '&Zeta;', u'\u0397': '&Eta;', u'\u0398': '&Theta;', u'\u0399': '&Iota;', u'\u039A': '&Kappa;', 179 u'\u039B': '&Lambda;', u'\u039C': '&Mu;', u'\u039D': '&Nu;', u'\u039E': '&Xi;', u'\u039F': '&Omicron;', u'\u03A0': '&Pi;', u'\u03A1': '&Rho;', u'\u03A3': '&Sigma;', 180 u'\u03A4': '&Tau;', u'\u03A5': '&Upsilon;', u'\u03A6': '&Phi;', u'\u03A7': '&Chi;', u'\u03A8': '&Psi;', u'\u03A9': '&Omega;', u'\u03B1': '&alpha;', u'\u03B2': '&beta;', 181 u'\u03B3': '&gamma;', u'\u03B4': '&delta;', u'\u03B5': '&epsilon;', u'\u03B6': '&zeta;', u'\u03B7': '&eta;', u'\u03B8': '&theta;', 182 u'\u03B9': '&iota;', u'\u03BA': '&kappa;', u'\u03BB': '&lambda;', u'\u03BC': '&mu;', u'\u03BD': '&nu;', u'\u03BE': '&xi;', 183 u'\u03BF': '&omicron;', u'\u03C0': '&pi;', u'\u03C1': '&rho;', u'\u03C2': '&sigmaf;', u'\u03C3': '&sigma;', u'\u03C4': '&tau;', u'\u03C5': '&upsilon;', 184 u'\u03C6': '&phi;', u'\u03C7': '&chi;', u'\u03C8': '&psi;', u'\u03C9': '&omega;', u'\u03D1': '&thetasym;', u'\u03D2': '&upsih;', u'\u03D6': '&piv;', u'\u2002': '&ensp;', 185 u'\u2003': '&emsp;', u'\u2009': '&thinsp;', u'\u200C': '&zwnj;', u'\u200D': '&zwj;', u'\u200E': '&lrm;', u'\u200F': '&rlm;', u'\u2013': '&ndash;', u'\u2014': '&mdash;', u'\u2018': '&lsquo;', 186 u'\u2019': '&rsquo;', u'\u201A': '&sbquo;', u'\u201C': '&ldquo;', u'\u201D': '&rdquo;', u'\u201E': '&bdquo;', u'\u2020': '&dagger;', u'\u2021': '&Dagger;', u'\u2022': '&bull;', 187 u'\u2026': '&hellip;', u'\u2030': '&permil;', u'\u2032': '&prime;', u'\u2033': '&Prime;', u'\u2039': '&lsaquo;', u'\u203A': '&rsaquo;', u'\u203E': '&oline;', u'\u2044': '&frasl;', 188 u'\u20AC': '&euro;', u'\u2111': '&image;', u'\u2118': '&weierp;', u'\u211C': '&real;', u'\u2122': '&trade;', u'\u2135': '&alefsym;', u'\u2190': '&larr;', u'\u2191': '&uarr;', 189 u'\u2192': '&rarr;', u'\u2193': '&darr;', u'\u2194': '&harr;', u'\u21B5': '&crarr;', u'\u21D0': '&lArr;', u'\u21D1': '&uArr;', u'\u21D2': '&rArr;', u'\u21D3': '&dArr;', u'\u21D4': '&hArr;', 190 u'\u2200': '&forall;', u'\u2202': '&part;', u'\u2203': '&exist;', u'\u2205': '&empty;', u'\u2207': '&nabla;', u'\u2208': '&isin;', u'\u2209': '&notin;', u'\u220B': '&ni;', 191 u'\u220F': '&prod;', u'\u2211': '&sum;', u'\u2212': '&minus;', u'\u2217': '&lowast;', u'\u221A': '&radic;', u'\u221D': '&prop;', u'\u221E': '&infin;', u'\u2220': '&ang;', u'\u2227': '&and;', 192 u'\u2228': '&or;', u'\u2229': '&cap;', u'\u222A': '&cup;', u'\u222B': '&int;', u'\u2234': '&there4;', u'\u223C': '&sim;', u'\u2245': '&cong;', u'\u2248': '&asymp;', u'\u2260': '&ne;', 193 u'\u2261': '&equiv;', u'\u2264': '&le;', u'\u2265': '&ge;', u'\u2282': '&sub;', u'\u2283': '&sup;', u'\u2284': '&nsub;', u'\u2286': '&sube;', u'\u2287': '&supe;', u'\u2295': '&oplus;', 194 u'\u2297': '&otimes;', u'\u22A5': '&perp;', u'\u22C5': '&sdot;', u'\u2308': '&lceil;', u'\u2309': '&rceil;', u'\u230A': '&lfloor;', u'\u230B': '&rfloor;', u'\u27E8': '&lang;', 195 u'\u27E9': '&rang;', u'\u25CA': '&loz;', u'\u2660': '&spades;', u'\u2663': '&clubs;', u'\u2665': '&hearts;', u'\u2666': '&diams;'} 196 197 strOut = "" 198 if _unicodeIn is not None: 199 for i in _unicodeIn: 200 if i in dico: 201 strOut += dico[i] 202 else: 203 strOut += str(i) 204 return strOut
205
206 -class EdnaPlugin(object):
207 """ 208 represents an EDNA Plugin: authore, date, doc, datamodel, ... 209 """ 210 strEdnaHome = strEdnaHome 211 dictXSD = {} #key= XSDataTruc value=path to XSD image/edml
212 - def __init__(self, _strPath):
213 self.dirname, self.basename = os.path.split(_strPath) 214 self.path = _strPath 215 if not(self.basename.startswith("EDPlugin") and self.basename.endswith(".py")): 216 self.isaPlugin = False 217 raise RuntimeError("Not an EDNA Plugin: %s" % _strPath) 218 self.name = self.basename[:-3] 219 self.project = _strPath.split(os.sep)[0] 220 if len(self.project) == 0: 221 self.project = _strPath.split(os.sep)[1] 222 self.abspath = os.path.abspath(os.path.join(self.strEdnaHome, _strPath)) 223 self.date = None 224 self.author = None 225 self.license = None 226 self.copyright = None 227 self.type = None 228 self.moduleDoc = [] 229 self.classDoc = [] 230 self.type = "Plugins (other)" 231 self.isaPlugin = True 232 self.__coding = None 233 self.datamodel = {} 234 if self.dictXSD == {}: 235 self.loadXSD()
236 237
238 - def analyse(self):
239 """ 240 Parse the source code to analyse the plugin 241 """ 242 print("Analysing: %s" % self.name) 243 lines = open(os.path.join(self.strEdnaHome, self.path)).readlines() 244 classline = None 245 # moduledoc = None 246 starter = None 247 coding = None 248 lstmoduledoc = [] 249 for line in lines: 250 if ("coding:" in line) and (coding is None): 251 coding = line[line.index("coding:") + 7:].split()[0].strip() 252 if "#" in line: 253 doc = line[:line.index("#")].rstrip() 254 if line.startswith("__author__") and "=" in line: 255 if coding is not None: 256 self.author = eval(line.split("=")[1]).decode(coding) 257 else: 258 self.author = eval(line.split("=")[1]) 259 if line.startswith("__authors__") and "=" in line: 260 if coding is not None: 261 self.author = ", ".join(eval(line.split("=")[1])).decode(coding) 262 else: 263 self.author = ", ".join(eval(line.split("=")[1])) 264 if line.startswith("__copyright__") and "=" in line: 265 if coding is not None: 266 self.copyright = eval(line.split("=")[1]).decode(coding) 267 else: 268 self.copyright = eval(line.split("=")[1]) 269 if line.startswith("__date__") and "=" in line: 270 if coding is not None: 271 self.date = eval(line.split("=")[1]).decode(coding) 272 else: 273 self.date = eval(line.split("=")[1]) 274 275 if line.startswith("__license__") and "=" in line: 276 if coding is not None: 277 self.license = eval(line.split("=")[1]).decode(coding) 278 else: 279 self.license = eval(line.split("=")[1]) 280 if (line.startswith("class") and line.split()[1].startswith(self.name)): 281 classline = line 282 if line.strip().startswith("self.setXSDataInputClass("): 283 self.datamodel[(line.split("(", 1)[1].split(")", 1)[0].split(",")[0].split(".")[0]).strip()] = None 284 285 if (self.moduleDoc == []) and (starter is not None) and (lstmoduledoc != []): 286 if starter in line: 287 lstmoduledoc.append(line[:line.index(starter)]) 288 self.moduleDoc = lstmoduledoc 289 else: 290 lstmoduledoc.append(line) 291 292 if (self.moduleDoc == []) and (starter is None): 293 if line.startswith("'''"): 294 starter = "'''" 295 elif line.startswith('"""'): 296 starter = '"""' 297 elif line.startswith("'"): 298 starter = "'" 299 elif line.startswith('"'): 300 starter = '"' 301 else: 302 starter = None 303 if starter is not None: 304 if line.strip().endswith(starter) and (len(line) > (2 * len(starter))): 305 self.moduleDoc = [line[len(starter):-len(starter)]] 306 else: 307 lstmoduledoc.append(line[len(starter):]) 308 309 for xsdIn in self.datamodel: 310 for line in lines: 311 if line.startswith("from") and ("import" in line) and (xsdIn in line): 312 self.datamodel[xsdIn] = line.split()[1] 313 break 314 315 starter = None 316 if classline is not None: 317 lstclasstypes = classline.split("(", 1) 318 if len(lstclasstypes) == 1: 319 self.isaPlugin = False 320 print("ERROR: Does not inherit from EDPlugin: %s" % self.name) 321 return 322 classtypes = lstclasstypes[1].strip() 323 if classtypes.startswith("EDPluginControl"): 324 self.type = "Control Plugins" 325 elif classtypes.startswith("EDPluginExec"): 326 self.type = "Execution Plugins" 327 else: 328 self.isaPlugin = False 329 raise RuntimeError("Does not look like an EDNA Plugin: %s" % self.path) 330 return 331 idx = lines.index(classline) + 1 332 lstclassdoc = [] 333 doc = lines[idx ].strip() 334 if "#" in doc: 335 doc = doc[:doc.index["#"]].strip() 336 if doc.startswith("'''"): 337 starter = "'''" 338 elif doc.startswith('"""'): 339 starter = '"""' 340 elif doc.startswith("'"): 341 starter = "'" 342 elif doc.startswith('"'): 343 starter = '"' 344 else: 345 starter = None 346 if starter is not None: 347 if doc.endswith(starter) and (len(doc) > (2 * len(starter))): 348 lstclassdoc.append(doc[len(starter):-len(starter)]) 349 else: 350 lstclassdoc.append(doc[len(starter):]) 351 bFinished = False 352 while not bFinished: 353 idx += 1 354 doc = lines[idx ].strip() 355 if "#" in doc: 356 doc = doc[:doc.index("#")].strip() 357 if starter in doc: 358 lstclassdoc.append(doc[:doc.index(starter)]) 359 bFinished = True 360 else: 361 lstclassdoc.append(doc) 362 363 self.classDoc = lstclassdoc 364 self.moduleDoc = [i for i in self.moduleDoc if i.strip() != "" ] 365 self.classDoc = [i for i in self.classDoc if i.strip() != "" ] 366 if coding is not None: 367 newModuleDoc = [] 368 newClassDoc = [] 369 for line in self.moduleDoc: 370 try: 371 dec = line.decode(coding) 372 except Exception: 373 dec = line 374 print("Unable to decode %s with %s" % (line, coding)) 375 else: 376 newModuleDoc.append(dec) 377 self.moduleDoc = newModuleDoc 378 for line in self.classDoc: 379 try: 380 dec = line.decode(coding) 381 except Exception: 382 dec = line 383 print("Unable to decode %s with %s" % (line, coding)) 384 else: 385 newClassDoc.append(dec) 386 self.classDoc = newClassDoc 387 self.isaPlugin = True 388 self.__coding = coding
389 390
391 - def getHtml(self, coding=None):
392 """ 393 Generate a web page with the documentation for the plugin 394 """ 395 if coding is None: 396 coding = self.__coding 397 if coding is None: 398 try: 399 import locale 400 except ImportError: 401 coding = "ascii" 402 else: 403 coding = locale.getdefaultlocale()[1] 404 if coding is None: 405 coding = "ascii" 406 407 lstStr = ["<html>", "<head>", "<title>EDNA Plugin: %s</title>" % self.name, "</head>", "<body>", "<center><h1>EDNA Plugin: %s</h1></center>" % self.name, "<table>"] 408 lstStr.append("<tr><td>Name:</td><td>%s</td</tr>" % self.name) 409 lstStr.append("<tr><td>Project:</td><td>%s</td</tr>" % self.project) 410 lstStr.append("<tr><td>Path:</td><td>%s</td</tr>" % self.path) 411 lstStr.append("<tr><td>Author:</td><td>%s</td</tr>" % unicode2html(self.author)) 412 lstStr.append("<tr><td>Date:</td><td>%s</td</tr>" % unicode2html(self.date)) 413 lstStr.append("<tr><td>Copyright:</td><td>%s</td</tr>" % unicode2html(self.copyright)) 414 lstStr.append("<tr><td>License:</td><td>%s</td</tr>" % unicode2html(self.license)) 415 lstStr.append("<tr><td>Module doc:</td><td>%s</td</tr>" % "<br>".join([unicode2html(i) for i in self.moduleDoc])) 416 lstStr.append("<tr><td>Class doc:</td><td>%s</td</tr>" % "<br>".join([unicode2html(i) for i in self.classDoc])) 417 lstStr += ["</table><hr>"] 418 419 onpage = {} 420 for datamodel in self.datamodel: 421 if self.datamodel[datamodel] is None: 422 continue 423 for datamodelImg in self.dictXSD: 424 if datamodelImg.startswith(self.datamodel[datamodel]): 425 if datamodelImg in onpage: 426 onpage[datamodelImg].append(datamodel) 427 else: 428 onpage[datamodelImg] = [datamodel] 429 430 for img in onpage: 431 lstStr.append("Datamodels: %s <br \ >" % ", ".join(onpage[img])) 432 if self.dictXSD[img].endswith(".png"): 433 lstStr.append("<img src='%s.png'><hr>" % img) 434 elif self.dictXSD[img].endswith(".edml"): 435 lstStr += [edml2html(open(self.dictXSD[img]).read()), "<hr>"] 436 lstStr.append("</body></html>") 437 438 return os.linesep.join(lstStr)
439 440 @classmethod
441 - def loadXSD(cls):
442 """ 443 look for all datamodel images. 444 """ 445 fullPath = "" 446 if cls.dictXSD == {}: 447 for root, dirs, files in os.walk(strEdnaHome, topdown=False): 448 for name in files: 449 base, ext = os.path.splitext(name) 450 if name.startswith("XSData") and (ext in [".edml", ".png"]): 451 fullPath = os.path.join(root, name) 452 if fullPath.startswith(strDest): 453 try: 454 os.remove(fullPath) 455 except IOError: 456 print("Unable to remove %s" % fullPath) 457 elif base in cls.dictXSD : 458 if os.stat(fullPath)[stat.ST_MTIME] > os.stat(cls.dictXSD[base])[stat.ST_MTIME]: 459 cls.dictXSD[base] = fullPath 460 else: 461 cls.dictXSD[base] = fullPath
462
463 464 -def edml2html(chaine):
465 """ 466 Convert an EDML file to a piece of HTML string 467 @param chaine: input string (EDML format) 468 @type chaine: string 469 """ 470 COLORS = {'red':'FF0000', 'orange':'FF4500', 'yellow':'FFFF00', 'green':'00EE00', 'magenta':'FF00FF', 'cyan':'00FFFF', 'blue':'0000FF', 471 'violet':'D02090', 'black':'000000', 'gray':'BEBEBE'} 472 dictInst = {'targetNamespace': 'red', 473 'complex': 'blue', 474 'type': 'blue', 475 'COMMENT': 'green', 476 'package': 'orange', 477 "optional": "orange", 478 "[": "orange", 479 "]": "orange", 480 ":": "violet", 481 "{": "blue", 482 "}": "blue", 483 } 484 485 listStruct = [] 486 for idx, subchain in enumerate(chaine.split('"')): 487 if idx % 2 == 0: 488 listLines = [] 489 for line in subchain.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;").replace(" ", "&nbsp;").split("\n"): 490 for key in dictInst: 491 pos = line.find(key) 492 if pos >= 0: 493 line = '%s<FONT COLOR="%s">%s</FONT>%s' % (line[:pos], COLORS[dictInst[key]], line[pos:pos + len(key)], line[pos + len(key):]) 494 listLines.append(line) 495 listStruct.append("<BR>\n".join(listLines)) 496 else: 497 listStruct.append('<FONT COLOR="%s">"%s"</FONT>' % (COLORS[dictInst['COMMENT']], subchain.replace("\n", "<BR>\n"))) 498 return "".join(listStruct)
499 500 501 if __name__ == "__main__": 502 strDest = os.path.join(os.getcwd() , "edna") 503 if len(sys.argv) > 1: 504 strDest = os.path.abspath(sys.argv[1]) 505 if not os.path.isdir(strDest): 506 os.makedirs(strDest) 507 datas = getPlugins(strEdnaHome, strDest) 508 txt = prettyHtml(*datas) 509 open(strDest + ".html", "w").write(txt) 510