00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 import os.path, sys
00025
00026 class PyGME_Generator(object):
00027
00028 def __init__(self, baseFolder):
00029 [setattr(self, x, None) for x in ('specPath', 'genFolder', 'registry', 'componentPath')]
00030 self.baseFolder = baseFolder
00031 self.register = False
00032 self.defaultSpecification = "component.xml"
00033 self.specifications = {'tooltip' : '', 'iconpath' : '', 'clsid' : self.generateUUID() }
00034
00035 def processCommandLine(self):
00036
00037 for arg in sys.argv:
00038 if arg.startswith('-register'):
00039 self.register = True
00040 sarg = arg.split('=')
00041 self.registry = len(sarg) == 2 and sarg[1] == 'system' and 2 or 1
00042 sys.argv.remove(arg)
00043 break
00044
00045 self.specPath = len(sys.argv) > 1 and os.path.abspath(sys.argv[1]) or os.path.join(self.baseFolder, self.defaultSpecification)
00046 if not (os.path.exists(self.specPath) and os.path.isfile(self.specPath)):
00047 print "Component specification file path '%s' does not exist or is not a file." % self.specPath
00048 raise Exception()
00049 self.genFolder = os.path.dirname(self.specPath)
00050
00051 def processComponentSpecification(self):
00052 specDict = self.specifications
00053 from xml.dom.minidom import parse, Element
00054 try:
00055 specXML = parse(os.path.join(self.specPath))
00056 except Exception, e:
00057 print "Error parsing XML specification file: %s." % e
00058 raise
00059 de = specXML.documentElement
00060 for attr in ('name', 'version', 'type', 'paradigm'):
00061 specDict[attr] = getattr(de.attributes.get(attr), 'value', None)
00062 if specDict[attr] is None:
00063 print "Attribute '%s' is missing from 'component' tag."
00064 if attr == 'type' and specDict[attr] and specDict[attr] not in ('Interpreter', 'Addon'):
00065 print "Unrecognized component type. Must be either 'Interpreter' or 'Addon'."
00066 specDict[attr] = None
00067 if None in specDict.values():
00068 print "Terminating due to component specification errors."
00069 raise Exception()
00070
00071 if specDict['type'] == 'Interpreter':
00072 for c in de.childNodes:
00073 if isinstance(c, Element):
00074 specDict[c.nodeName] = getattr(c.attributes.get('value'), 'value', None)
00075 if 'iconpath' in specDict:
00076 iconPath = os.path.normpath(specDict['iconpath'].replace('\\', os.path.sep))
00077 if not os.path.isabs(iconPath):
00078 iconPath = os.path.join(self.baseFolder, iconPath)
00079 if not (os.path.exists(iconPath) and os.path.isfile(iconPath)):
00080 print "Component icon path '%s' does not exist or is not a file." % iconPath
00081 raise Exception()
00082 specDict['icondir'], specDict['iconpath'] = os.path.split(iconPath)
00083
00084 def generateUUID(self):
00085 try:
00086 import pythoncom
00087 generator = pythoncom.CreateGuid
00088 except Exception, e:
00089 print "Unable to import pythoncom module. Your Python installation appears to lack the required 'Win32 Extensions for Python' package."
00090 if self.register:
00091 self.register = False
00092 print "Unable to register GME COM components."
00093 try:
00094 import uuid
00095 generator = lambda : str(uuid.uuid1()).upper()
00096 print "Generating component using built-in Python uuid module in place of pythoncom.CreateGuid."
00097 except Exception,e:
00098 "Unable to generate component. No available UUID generator."
00099 raise
00100 return generator()
00101
00102 def generateComponent(self):
00103 if self.specifications['name'].find('.') != -1:
00104 print "Component name should not contain '.'"
00105 raise ValueError()
00106 try:
00107 from Generator import InterpreterTemplate, AddonTemplate
00108 except Exception,e:
00109 print "Unable to import component templates. Not found relative to PyGME.py or on PythonPath."
00110 raise
00111 template = self.specifications['type'] == 'Interpreter' and InterpreterTemplate or AddonTemplate
00112 self.componentPath = os.path.join(self.genFolder, "%s.py" % self.specifications['name'])
00113 f = file(self.componentPath, "w")
00114 f.write(template % self.specifications)
00115 f.close()
00116
00117 def registerComponent(self):
00118 if self.register:
00119 if self.baseFolder not in sys.path:
00120 sys.path.insert(0, self.baseFolder)
00121 mod = __import__(self.specifications['name'])
00122 comp = getattr(mod, self.specifications['name'])
00123 comp.RegisterSelf(self.registry, self.specifications['icondir'])
00124
00125 def generate():
00126 print "PyGME. Starting generation..."
00127 try:
00128 generator = PyGME_Generator(baseFolder=os.path.dirname(os.path.abspath(__file__)))
00129 generator.processCommandLine()
00130 generator.processComponentSpecification()
00131 generator.generateComponent()
00132 generator.registerComponent()
00133 print "PyGME. Component generation complete. Your generated component is in '%s'." % generator.componentPath
00134 except Exception,e:
00135 print "PyGME. Component generation failed."
00136 raise
00137
00138 if __name__ == "__main__":
00139 generate()