def lateInit(self): # create a controller self.ctt = Controller(*(self._arg), **(self._kwarg)) # loaders self.loaderList.itemSelectionChanged.connect(self.activateLoader) self.loaderView.anchorClicked.connect(self.openURL) for a in sorted(self.ctt.loaders): self.loaderList.addItem(a) self.loaderList.item(0).setSelected(True) # generators self.activeGenerator = None self.generatorListReloadButton.pressed.connect( self.updateGeneratorList) self.generatorExplorerButton.pressed.connect(self.exploreGenerators) self.generatorList.itemSelectionChanged.connect(self.activateGenerator) self.generatorView.anchorClicked.connect(self.openURL) self.generateButton.clicked.connect(self.executeGenerator) self.updateGeneratorList(rescan=False) # buttons self.uriLoadButton.clicked.connect(self.getUriList) self.outputLoadButton.clicked.connect(self.getOutputFile) # set preferences from cfg if self.cfg.has_section('PREFERENCES'): p = self.cfg['PREFERENCES'] self.uriInput.setText(p.get('uriList', '')) self.outputInput.setText(p.get('outputFile', '')) g = p.get('generator', '') for x in range(self.generatorList.count()): i = self.generatorList.item(x) if i.text() == g: i.setSelected(1) break
def main(): """main function when CoTeTo is used on the command line""" parser = argparse.ArgumentParser(description=descr) grp = parser.add_argument_group('path settings') grp.add_argument('-p', '--search-path', metavar='PATH', help='search path for generators (separated by ;)') grp = parser.add_argument_group('general information') grp.add_argument('-a', '--list-loaders', action='store_true', help='list available loaders') grp.add_argument('-l', '--list-generators', action='store_true', help='list available code generators') grp.add_argument('-d', '--debug', metavar='LEVEL', help='set debug level to show on stderr (1...5)') grp = parser.add_argument_group('generator actions') grp.add_argument( '-g', '--generator', metavar='GEN', nargs=1, help='select generator GEN (needed for the following actions)') grp.add_argument('-o', '--output', metavar='FILE', nargs=1, help='use FILE for output instead of stdout') grp.add_argument('-s', '--show-generator', action='store_true', help='show information on generator (needs -g)') grp.add_argument( 'data_source', metavar='dataSource', type=str, default='', nargs='*', help= 'execute the generator with these data source URIs passed to the loader (needs -g)' ) args = parser.parse_args() # first read config file for default values defaults = { 'GeneratorPath': os.environ.get('COTETO_GENERATORS', ''), 'LogLevel': '0', } cfg = configparser.ConfigParser(defaults) homeVar = { 'win32': 'USERPROFILE', 'linux': 'HOME', 'linux2': 'HOME', 'darwin': 'HOME' }.get(sys.platform) cfg.read(os.path.join(os.environ.get(homeVar, ''), '.CoTeTo.cfg')) # generatorPath gp = args.search_path or cfg['DEFAULT']['GeneratorPath'] generatorPath = [p for p in gp.split(';') if p] # logLevel logLevel = 10 * cfg.getint('DEFAULT', 'LogLevel') if args.debug: logLevel = 10 * int(args.debug) # create teh controller ctt = Controller(generatorPath, logLevel=logLevel) if args.list_loaders: for n in sorted(ctt.loaders): l = ctt.loaders[n] print('%s%s (%s):%s\t%s' % (nl, n, l.author, nl, l.description)) print() return 0 elif args.list_generators: for n in sorted(ctt.generators): g = ctt.generators[n] print('%s%s (%s):%s\t%s' % (nl, n, g.author, nl, g.description)) print() return 0 # from here we need a valid generator name! if not args.generator: parser.error( 'Please specify a generator with -g or --generator or get help with -h!' + nl) if not args.generator[0] in ctt.generators: parser.error('This generator is not valid, list choices with -l!' + nl) g = ctt.generators[args.generator[0]] if args.show_generator: # FIXME print(g.infoText('txt')) return 0 elif args.data_source: # execute the generator o = g.execute(args.data_source) if len(o) == 1: # single file output ext = list(o.keys())[0] if args.output: outFile = open(args.output[0] + ext, 'w') outFile.write(o[ext].read()) outFile.close() else: sys.stdout.write(o[ext].read()) else: # multi file output if args.output: for ext in o: outFile = open(args.output[0] + ext, 'w') outFile.write(o[ext].read()) outFile.close() else: for ext in o: sys.stdout.write('### FILE: %s\n' % ext) sys.stdout.write(o[ext].read()) return 0 else: parser.print_help()
class CoTeToWidget(QtWidgets.QWidget): def __init__(self, app, resPath, cfg, *arg, **kwarg): QtWidgets.QWidget.__init__(self) self.app = app # load the Icons sys.path.insert(0, resPath) import Icons_rc # load the ui self.ui = uic.loadUi(os.path.join(resPath, 'CoTeTo-GUI.ui'), self) self.setWindowTitle('CoTeTo GUI | Version: %s' % (CoTeTo.__version__)) self.cfg = cfg self._arg = arg self._kwarg = kwarg # create a logView? if 'logLevel' in kwarg and kwarg['logLevel'] > 0: self.logView = LogViewer(resPath, *arg, **kwarg) self.coTeToMainView.addTab(self.logView, 'Messages') kwarg['logHandler'] = self.logView.logHandler # get the logger self.logger = logging.getLogger('CoTeTo') # replace systems exception hook sys.excepthook = self.exceptionHook # do more initialization later QtCore.QTimer().singleShot(500, self.lateInit) def lateInit(self): # create a controller self.ctt = Controller(*(self._arg), **(self._kwarg)) # loaders self.loaderList.itemSelectionChanged.connect(self.activateLoader) self.loaderView.anchorClicked.connect(self.openURL) for a in sorted(self.ctt.loaders): self.loaderList.addItem(a) self.loaderList.item(0).setSelected(True) # generators self.activeGenerator = None self.generatorListReloadButton.pressed.connect( self.updateGeneratorList) self.generatorExplorerButton.pressed.connect(self.exploreGenerators) self.generatorList.itemSelectionChanged.connect(self.activateGenerator) self.generatorView.anchorClicked.connect(self.openURL) self.generateButton.clicked.connect(self.executeGenerator) self.updateGeneratorList(rescan=False) # buttons self.uriLoadButton.clicked.connect(self.getUriList) self.outputLoadButton.clicked.connect(self.getOutputFile) # set preferences from cfg if self.cfg.has_section('PREFERENCES'): p = self.cfg['PREFERENCES'] self.uriInput.setText(p.get('uriList', '')) self.outputInput.setText(p.get('outputFile', '')) g = p.get('generator', '') for x in range(self.generatorList.count()): i = self.generatorList.item(x) if i.text() == g: i.setSelected(1) break # end of preferences # general methods def exceptionHook(self, t, v, tb): """Show unhandled exceptions""" msg = ''.join(traceback.format_exception(t, v, tb)) self.logger.critical('An unhandled exception occured') print('*' * 40 + '\n' + msg + '*' * 40) QtWidgets.QMessageBox.critical( self, 'An unhandled exception occured', 'Please have a look at the <b>Messages</b> tab for details!') def openURL(self, url): """open an link target from the generator or loader view""" scheme = url.scheme() if scheme == 'file': # print(url) QtGui.QDesktopServices.openUrl(url) elif scheme == 'loader': a = url.authority().replace('___', '::').lower() i = self.loaderList.findItems(a, QtCore.Qt.MatchFixedString)[0] self.loaderList.setCurrentItem(i) self.loaderList.itemActivated.emit(i) self.coTeToMainView.setCurrentIndex(1) else: print('Unknown URL scheme:', url) def getUriList(self): flist = QtWidgets.QFileDialog.getOpenFileNames(self, 'Select Data Sources') if flist and flist[0]: self.uriInput.setText(', '.join(flist[0])) def getOutputFile(self): f = QtWidgets.QFileDialog.getSaveFileName(self, 'Select Output File', '*') if f and f[0]: self.outputInput.setText(f[0]) # loader methods def activateLoader(self): items = self.loaderList.selectedItems() if items: loader = items[0].text() self.loaderView.clear() # FIXME: this is ugly, loader class is not instantiated yet ... but we need the information c = self.ctt.loaders[loader] self.loaderView.setText(c.infoText(c, 'html')) # generator methods def exploreGenerators(self): for p in self.ctt.generatorPath: QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(p)) def updateGeneratorList(self, rescan=True): # get old selection selItems = self.generatorList.selectedItems() selected = None if selItems: selected = selItems[0].text() if rescan: self.ctt.rescanGenerators() self.generatorList.clear() i = 0 for n in sorted(self.ctt.generators): self.generatorList.addItem(n) if n == selected: # select previously selected generator self.generatorList.item(i).setSelected(True) i += 1 if not self.generatorList.selectedItems(): # nothing selected, select the first in the list self.generatorList.item(0).setSelected(True) def activateGenerator(self): sel = self.generatorList.selectedItems() if sel: gen = sel[0].text() else: return self.activeGenerator = self.ctt.generators[gen] self.generatorView.clear() self.generatorView.setText(self.activeGenerator.infoText('html')) def executeGenerator(self): line = self.uriInput.text() uriList = [u.strip() for u in line.split(',')] outputBase = str(self.outputInput.text()) if not outputBase: tmp, outputBase = tempfile.mkstemp(suffix='.txt', text=True) self.outputInput.setText(outputBase) if not os.path.isabs(outputBase): outputBase = os.path.abspath(outputBase) x = self.activeGenerator.execute(uriList, outputBase) if self.openOutputButton.isChecked(): for ext in x: QtGui.QDesktopServices.openUrl( QtCore.QUrl.fromLocalFile(x[ext])) def closeEvent(self, e): # first reset output streams to standard settings XStream.reset() # save preferences to config file if hasattr(self.cfg, 'path'): uriList = self.uriInput.text() outputFile = self.outputInput.text() generator = '' tmp = self.generatorList.selectedItems() if tmp: generator = tmp[0].text() try: c = self.cfg p = 'PREFERENCES' if not c.has_section(p): c.add_section(p) c.set(p, 'uriList', uriList) c.set(p, 'outputFile', outputFile) c.set(p, 'generator', generator) with open(c.path, 'w') as configfile: c.write(configfile) except BaseException: # silently ignore errors # FIXME: is this a good idea? But where should the errors appear? pass e.accept()
# # This is an example of the usage of CoTeTo as a python module. # # check if we are running in the development folder - # just a hack to run this script without installing CoTeTo first - # usually not needed for users import os, sys parent = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) if os.path.isfile(os.path.join(parent, 'setup.py')): sys.path.insert(0, parent) #### Example Code # 1. import the controller class from CoTeTo from CoTeTo.Controller import Controller # 2. initialize a controller instance # for a list of optional arguments see CoTeTo/Controller.py con = Controller() # 3. choose a generator ... # (get a list of available generators with print(con.generators.keys())) gen = con.generators['Example01Mako::1.0'] # 4. ... and execute it! # arguments are: # a list of input URIs (not used with the dummy loader) # a filename or prefix for the output gen.execute(('spam', ), 'ModuleTestOutput.txt')