def main(self, args=None): self.progPath = os.path.join(os.getcwd(), sys.argv[0]) self.otherKeys = self.otherKeys # pick up class level value self.parseArgs(args) modelName = self.args.get('model') if not modelName: classesName = self.args.get('classes') if not classesName: self.usage('No model or classes file specified.') outDir = self.args.get('outDir', os.curdir) self.requireDir(outDir) outDir = os.path.join(outDir, 'GeneratedDocs') self.requireDir(outDir) self.outDir = outDir from MiddleKit.Core.Model import Model if modelName: self.model = Model(modelName, havePythonClasses=False) else: self.model = Model(classesFilename=classesName, havePythonClasses=False) source = os.path.join(os.path.dirname(self.progPath), self.sourceStyleSheetFilename) dest = os.path.join(outDir, self.destStyleSheetFilename) shutil.copyfile(source, dest) #self.dump() self.generateHTML()
def main(self, args=None): self.progPath = os.path.join(os.getcwd(), sys.argv[0]) self.otherKeys = self.otherKeys # pick up class level value self.parseArgs(args) modelName = self.args.get('model', None) if not modelName: classesName = self.args.get('classes', None) if not classesName: self.usage('No model or classes file specified.') outDir = self.args.get('outDir', os.curdir) self.requireDir(outDir) outDir = os.path.join(outDir, 'GeneratedDocs') self.requireDir(outDir) self.outDir = outDir from MiddleKit.Core.Model import Model if modelName: self.model = Model(modelName, havePythonClasses=0) else: self.model = Model(classesFilename=classesName, havePythonClasses=0) source = os.path.join(os.path.dirname(self.progPath), self.sourceStyleSheetFilename) dest = os.path.join(outDir, self.destStyleSheetFilename) shutil.copyfile(source, dest) #self.dump() self.generateHTML()
def test(modelFilename, workDir=workDir, toTestDir='../'): """ modelFilename: the correct filename to the existing model workDir: the directory to remove and create and then put the generated files in toTestDir: a relative path to get from inside the workDir back to the MiddleKit/Tests dir In most cases, the defaults for workDir and toTestDir are sufficient. In funkalicious cases, like the MKMultipleStores test, overriding these defaults comes in handy. """ rmdir(workDir) # get rid of files from previous runs os.mkdir(workDir) # make a space for the files from this run # Run generate, load the model, and import some classes Generate().main('Generate.py --outdir %s --db MySQL --model %s' % (workDir, modelFilename)) curDir = os.getcwd() os.chdir(workDir) try: model = Model(toTestDir+modelFilename) importPyClasses(model.klasses()) return model finally: os.chdir(curDir)
def makeModel(self): """ Constructs and returns a MiddleKit model for use with UserKit. """ from MiddleKit.Core.Model import Model from MiddleKit.Core.Klasses import Klasses from MiddleKit.Core.Klass import Klass from MiddleKit.Core.StringAttr import StringAttr klass = Klass() klass.readDict({'Class': 'UserForMKTest'}) klass.addAttr( StringAttr({ 'Name': 'name', 'Type': 'string', 'isRequired': 1, })) klass.addAttr( StringAttr({ 'Name': 'password', 'Type': 'string', 'isRequired': 1, })) klass.addAttr( StringAttr({ 'Name': 'externalId', 'Type': 'string', 'isRequired': 0, })) model = Model() model.setName(self.__class__.__name__) model.readParents([]) klasses = model.klasses() klasses.addKlass(klass) model.awakeFromRead( ) # @@ 2001-02-17 ce: a little weird regarding name return model
def test(modelFilename, configFilename, workDir=workDir, toTestDir='../'): """Test method. modelFilename: the correct filename to the existing model workDir: the directory to remove and create and then put the generated files in toTestDir: a relative path to get from inside the workDir back to the MiddleKit/Tests dir In most cases, the defaults for workDir and toTestDir are sufficient. In funkalicious cases, like the MKMultipleStores test, overriding these defaults comes in handy. """ rmdir(workDir) # get rid of files from previous runs os.mkdir(workDir) # make a space for the files from this run # Run generate, load the model, and import some classes command = os.path.normpath('../Design/Generate.py') command += ' --outdir %s --db %s --model %s' % (workDir, dbName, modelFilename) if configFilename: command += ' --config ' + configFilename print command Generate().main(command) curDir = os.getcwd() os.chdir(workDir) try: if 0: print 'getcwd:', os.getcwd() print 'listdir:', os.listdir('.') print 'model path:', repr(toTestDir+modelFilename) print 'sys.path', sys.path model = Model(toTestDir+modelFilename, configFilename=configFilename) importPyClasses(model.klasses()) return model finally: os.chdir(curDir)
def test(modelFilename, configFilename, workDir=workDir, toTestDir='../'): """Test method. modelFilename: the correct filename to the existing model workDir: the directory to remove and create and then put the generated files in toTestDir: a relative path to get from inside the workDir back to the MiddleKit/Tests dir In most cases, the defaults for workDir and toTestDir are sufficient. In funkalicious cases, like the MKMultipleStores test, overriding these defaults comes in handy. """ rmdir(workDir) # get rid of files from previous runs os.mkdir(workDir) # make a space for the files from this run # Run generate, load the model, and import some classes command = os.path.normpath('../Design/Generate.py') command += ' --outdir %s --db %s --model %s' % (workDir, dbName, modelFilename) if configFilename: command += ' --config ' + configFilename print(command) Generate().main(command) curDir = os.getcwd() os.chdir(workDir) try: if 0: print('getcwd:', os.getcwd()) print('listdir:', os.listdir('.')) print('model path:', repr(toTestDir + modelFilename)) print('sys.path', sys.path) model = Model(toTestDir + modelFilename, configFilename=configFilename) importPyClasses(model.klasses()) return model finally: os.chdir(curDir)
class Doc(object): sourceStyleSheetFilename = 'GenDocStyles.css' # in MiddleKit/Design/ destStyleSheetFilename = 'Styles.css' otherKeys = 'isDerived Min Max Enums'.split() def main(self, args=None): self.progPath = os.path.join(os.getcwd(), sys.argv[0]) self.otherKeys = self.otherKeys # pick up class level value self.parseArgs(args) modelName = self.args.get('model') if not modelName: classesName = self.args.get('classes') if not classesName: self.usage('No model or classes file specified.') outDir = self.args.get('outDir', os.curdir) self.requireDir(outDir) outDir = os.path.join(outDir, 'GeneratedDocs') self.requireDir(outDir) self.outDir = outDir from MiddleKit.Core.Model import Model if modelName: self.model = Model(modelName, havePythonClasses=False) else: self.model = Model(classesFilename=classesName, havePythonClasses=False) source = os.path.join(os.path.dirname(self.progPath), self.sourceStyleSheetFilename) dest = os.path.join(outDir, self.destStyleSheetFilename) shutil.copyfile(source, dest) #self.dump() self.generateHTML() def generateHTML(self): path = os.path.join(self.outDir, self.model.name() + '.html') wr = open(path, 'w').write wr(''' <html> <head> <link rel="stylesheet" type="text/css" href="%s"> </head> <body> <a name=#top></a> ''' % self.destStyleSheetFilename) wr('<div class="head1">%s Model (MiddleKit)</div>\n' % self.model.name()) wr('Generated on %s <br>\n' % time.asctime()) wr('From %s <br>\n' % self.model.filename()) wr('<br>\n') wr('<table>\n') wr('<tr class="Class">' '<td class="ClassName" colspan="3">Classes</td></tr>\n') wr('<tr class="AttrTitles"><td class=AttrTitles>In Alpha Order</td>' '<td class="AttrTitles">In Inheritance Order</td></tr>\n') wr('<tr><td style="vertical-align:top">\n') klasses = self.model.allKlassesInOrder() for klass in sorted(klasses, key=lambda klass: klass.name().lower()): name = klass.name() wr('<a href="#%s">%s</a><br>\n' % (name, name)) wr('<td style="vertical-align:top">') for klass in klasses: if not klass.superklass(): self.writeKlassLinkAndRecurse(wr, klass) wr('</table>\n') for klass in klasses: name = klass.name() wr(''' <a id="%(name)s"></a> <table class="Class"> <tr class="ClassName"> <td class="ClassName" colspan="7"> <table style="width:100%%"> <tr> <td class="ClassName">%(name)s</td> <td class="Top" style="text-align:right"><a href="#top">top</a></td> </tr> </table> </td> </tr> ''' % locals()) wr('<tr class="ClassInfo"><td class="ClassInfo" colspan="7">\n') # ancestor classes wr('<table>\n') if klass.get('isAbstract'): wr('<tr><td style="vertical-align:top">abstract:</td>' '<td style="vertical-align:top">yes</td></tr>\n') wr('<tr><td style="vertical-align:top">ancestors:</td>' '<td style="vertical-align:top">') ancestor = klass.superklass() if ancestor: while ancestor: name = ancestor.name() wr(' <a href="#%s">%s</a> ' % (name, name)) ancestor = ancestor.superklass() else: wr('none') wr('</td></tr>\n') # subclasses wr('<tr><td style="vertical-align:top">subclasses:</td>' '<td style="vertical-align:top">\n') if klass.subklasses(): for subklass in klass.subklasses(): name = subklass.name() wr('<a href="#%s">%s</a> ' % (name, name)) else: wr('none') wr('</td></tr>\n') # notes wr('<tr> <td style="vertical-align:top">notes:</td>' '<td style="vertical-align:top">') if klass.get('Notes'): wr(htmlEncode(klass['Notes'])) else: wr('none') wr('</td></tr>\n') wr('</table>\n') wr(''' <tr class="AttrTitles"> <td class="AttrTitles">Name</td> <td class="AttrTitles">Type</td> <td class="AttrTitles">IsRequired</td> <td class="AttrTitles">Default</td> <td class="AttrTitles">Notes</td> </tr> ''') for attr in klass.allAttrs(): # print attr values = Values(attr) if attr.klass() is klass: values['Prefix'] = '' else: values['Prefix'] = 'Inh' values['Type'] = attr.htmlForType() wr(''' <tr class="Attr"> <td class="%(Prefix)sAttrName">%(Name)s</td> <td class="%(Prefix)sAttr">%(Type)s</td> <td class="%(Prefix)sAttr">%(isRequired)s</td> <td class="%(Prefix)sAttr">%(Default)s</td> ''' % values) notes = [] if attr.get('Notes'): notes.append(htmlEncode(attr.get('Notes'))) for key in self.otherKeys: if attr.get(key) is not None: notes.append('%s = %s' % (key, attr[key])) if notes: notes = '<br>'.join(notes) notes = mystr(notes) values['Notes'] = notes # wr('<tr class=Attr><td class=%(Prefix)sAttr> </td>' # '<td class=%(Prefix)sAttrNotes colspan=7>%(Notes)s</td>' # '</tr>\n' % values) wr('<td class="%(Prefix)sAttrNotes">%(Notes)s</td>\n' % values) else: wr('<td class="%(Prefix)sAttrNotes"> </td>\n' % values) wr('</tr>') wr('</table>\n') wr('</body></html>\n') def writeKlassLinkAndRecurse(self, wr, klass, level=0): wr(' ' * level * 4) name = klass.name() wr('<a href="#%s">%s</a><br>\n' % (name, name)) level += 1 for klass in klass.subklasses(): self.writeKlassLinkAndRecurse(wr, klass, level) def dump(self): """Dump the class and attribute definitions in order. This is a simple example that you could expand to generate your own brand of HTML or some other output format. """ for klass in self.model.allKlassesInOrder(): print klass for attr in klass.allAttrs(): print attr def requireDir(self, d): if not os.path.exists(d): os.mkdir(d) elif not os.path.isdir(d): print 'Error: Output target, %s, is not a directory.' % d def parseArgs(self, args): self.parseGenericArgs(args) args = self.args if 'otherkeys' in args: self.otherKeys = args['otherkeys'] if isinstance(self.otherKeys, basestring): self.otherKeys = self.otherKeys.split() if 'morekeys' in args: moreKeys = args['morekeys'] if isinstance(moreKeys, basestring): moreKeys = moreKeys.split() self.otherKeys += list(moreKeys) def parseGenericArgs(self, args): if args is None: args = sys.argv[1:] values = {} for arg in args: parts = arg.split('=', 1) if len(parts) == 2: values[parts[0].lower()] = valueForString(parts[1]) else: values[parts[0].lower()] = True self.args = values def usage(self, errorMsg=None): progName = os.path.basename(sys.argv[0]) if errorMsg: print '%s: error: %s' % (progName, errorMsg) print ''' USAGE: %(progName)s model=FILENAME [OPTIONS] %(progName)s classes=FILENAME [OPTIONS] OPTIONS: [outDir=DIRNAME] [moreKeys="foo bar"] [otherKeys="foo bar"] NOTES: * If outDir is not specified, then the base filename (sans extension) is used. * GeneratedDocs is appended to the output directory. * The Notes column will also include the other keys: isDerived, Min, Max and Enums. * You can redefine those keys with the otherKeys argument. * But more typically, you would use moreKeys to _add_ keys specific to your model (i.e., user-defined rather than MiddleKit-defined). ''' % locals() print sys.exit(1)
class Doc: sourceStyleSheetFilename = 'GenDocStyles.css' # exists in MiddleKit/Design/ destStyleSheetFilename = 'Styles.css' otherKeys = 'isDerived Min Max Enums'.split() def main(self, args=None): self.progPath = os.path.join(os.getcwd(), sys.argv[0]) self.otherKeys = self.otherKeys # pick up class level value self.parseArgs(args) modelName = self.args.get('model', None) if not modelName: classesName = self.args.get('classes', None) if not classesName: self.usage('No model or classes file specified.') outDir = self.args.get('outDir', os.curdir) self.requireDir(outDir) outDir = os.path.join(outDir, 'GeneratedDocs') self.requireDir(outDir) self.outDir = outDir from MiddleKit.Core.Model import Model if modelName: self.model = Model(modelName, havePythonClasses=0) else: self.model = Model(classesFilename=classesName, havePythonClasses=0) source = os.path.join(os.path.dirname(self.progPath), self.sourceStyleSheetFilename) dest = os.path.join(outDir, self.destStyleSheetFilename) shutil.copyfile(source, dest) #self.dump() self.generateHTML() def generateHTML(self): path = os.path.join(self.outDir, self.model.name()+'.html') file = open(path, 'w') wr = file.write wr(''' <html> <head> <link rel=stylesheet type=text/css href=%s> </head> <body> <a name=#top></a> ''' % self.destStyleSheetFilename) wr('<div class=head1>%s Model (MiddleKit)</div>\n' % self.model.name()) wr('Generated on %s <br>\n' % time.asctime()) wr('From %s <br>\n' % self.model.filename()) wr('<br>\n') wr('<table border=0 cellpadding=2 cellspacing=2>\n') wr('<tr class=Class> <td class=ClassName colspan=3> Classes </td> </tr>\n') wr('<tr class=AttrTitles> <td class=AttrTitles> In Alpha Order </td> <td class=AttrTitles> In Inheritance Order </td> </tr>\n') wr('<tr> <td valign=top>\n') klasses = self.model.allKlassesInOrder()[:] klasses.sort(lambda a, b: cmp(a.name().lower(), b.name().lower())) for klass in klasses: name = klass.name() wr('<a href=#%s>%s</a> <br>\n' % (name, name)) wr('<td valign=top>') for klass in self.model.allKlassesInOrder(): if not klass.superklass(): self.writeKlassLinkAndRecurse(wr, klass) wr('</table>\n') for klass in self.model.allKlassesInOrder(): name = klass.name() wr(''' <a name="%(name)s"></a> <table class=Class cellspacing=2 cellpadding=2> <tr class=ClassName> <td class=ClassName colspan=7> <table border=0 cellpadding=0 cellspacing=0 width=100%%> <tr> <td class=ClassName> %(name)s </td> <td class=Top align=right> <a href=#top>top</a> </td> </tr> </table> </td> </tr> ''' % locals()) wr('<tr class=ClassInfo> <td class=ClassInfo colspan=7>\n') # ancestor classes wr('<table border=0 cellpadding=3 cellspacing=0>\n') if klass.get('isAbstract'): wr('<tr> <td valign=top> abstract: </td> <td valign=top> yes </td> </tr>\n') wr('<tr> <td valign=top> ancestors: </td> <td valign=top> ') ancestor = klass.superklass() if ancestor: while ancestor: name = ancestor.name() wr(' <a href=#%s>%s</a> ' % (name, name)) ancestor = ancestor.superklass() else: wr(' none ') wr('</td> </tr>\n') # subclasses wr('<tr> <td valign=top> subclasses: </td> <td valign=top>\n') if klass.subklasses(): for subklass in klass.subklasses(): name = subklass.name() wr(' <a href=#%s>%s</a> ' % (name, name)) else: wr('none') wr('</td> </tr>\n') # notes wr('<tr> <td valign=top> notes: </td> <td valign=top> ') if klass.get('Notes'): wr(htmlEncode(klass['Notes'])) else: wr('none') wr('</td> </tr>\n') wr('</table>\n') wr(''' <tr class=AttrTitles> <td class=AttrTitles> Name </td> <td class=AttrTitles> Type </td> <td class=AttrTitles> IsRequired </td> <td class=AttrTitles> Default </td> <td class=AttrTitles> Notes </td> </tr> ''') for attr in klass.allAttrs(): #print attr values = Values(attr) if attr.klass() is klass: values['Prefix'] = '' else: values['Prefix'] = 'Inh' values['Type'] = attr.htmlForType() wr(''' <tr class=Attr> <td class=%(Prefix)sAttrName> %(Name)s </td> <td class=%(Prefix)sAttr> %(Type)s </td> <td class=%(Prefix)sAttr> %(isRequired)s </td> <td class=%(Prefix)sAttr> %(Default)s </td> ''' % values) notes = [] if attr.get('Notes'): notes.append(htmlEncode(attr.get('Notes'))) for key in self.otherKeys: if attr.get(key) is not None: notes.append('%s = %s' % (key, attr[key])) if notes: notes = ' <br> '.join(notes) notes = mystr(notes) values['Notes'] = notes # wr('<tr class=Attr><td class=%(Prefix)sAttr> </td>' # '<td class=%(Prefix)sAttrNotes colspan=7>%(Notes)s</td>' # '</tr>\n' % values) wr('<td class=%(Prefix)sAttrNotes> %(Notes)s </td>\n' % values) else: wr('<td class=%(Prefix)sAttrNotes> </td>\n' % values) wr('</tr>') wr('</table>\n') wr('</body> </html>\n') def writeKlassLinkAndRecurse(self, wr, klass, level=0): wr(' '*level*4) name = klass.name() wr('<a href=#%s>%s</a> <br>\n' % (name, name)) level += 1 for klass in klass.subklasses(): self.writeKlassLinkAndRecurse(wr, klass, level) def dump(self): """ Dumps the class and attribute definitions in order. This is a simple example that you could expand to generate your own brand of HTML or some other output format. """ for klass in self.model.allKlassesInOrder(): print klass for attr in klass.allAttrs(): print attr def requireDir(self, d): if not os.path.exists(d): os.mkdir(d) elif not os.path.isdir(d): print 'Error: Output target, %s, is not a directory.' % d def parseArgs(self, args): self.parseGenericArgs(args) args = self.args if args.has_key('otherkeys'): self.otherKeys = args['otherkeys'] if type(self.otherKeys) in StringTypes: self.otherKeys = self.otherKeys.split() if args.has_key('morekeys'): moreKeys = args['morekeys'] if type(moreKeys) in StringTypes: moreKeys = moreKeys.split() self.otherKeys += list(moreKeys) def parseGenericArgs(self, args): if args is None: args = sys.argv[1:] values = {} for arg in args: parts = arg.split('=', 1) if len(parts) == 2: values[parts[0].lower()] = valueForString(parts[1]) else: values[parts[0].lower()] = 1 self.args = values def usage(self, errorMsg=None): progName = os.path.basename(sys.argv[0]) if errorMsg: print '%s: error: %s' % (progName, errorMsg) print ''' Usage: %(progName)s model=FILENAME [outDir=DIRNAME] [moreKeys="foo bar"] [otherKeys="foo bar"] %(progName)s classes=FILENAME [outDir=DIRNAME] [moreKeys="foo bar"] [otherKeys="foo bar"] * If outDir is not specified, then the base filename (sans extension) is used. * GeneratedDocs is appended to the output directory. * The Notes column will also include the other keys: isDerived, Min, Max and Enums. * You can redefine those keys with the otherKeys argument. * But more typically, you would use moreKeys to _add_ keys specific to your model (i.e., user-defined rather than MiddleKit-defined). ''' % locals() print sys.exit(1)