def canConnect(self, outWidgetDesc, inWidgetDesc): """Can connect any output from outWidgetDesc to input from inWidgetDesc. """ if (outWidgetDesc, inWidgetDesc) not in self._canConnectCache: ret = any(orngSignalManager.canConnect( resolveSignal(out), resolveSignal(in_), dynamic=True) \ for out in outWidgetDesc.outputs \ for in_ in inWidgetDesc.inputs ) self._canConnectCache[(outWidgetDesc, inWidgetDesc)] = ret return self._canConnectCache[(outWidgetDesc, inWidgetDesc)]
def readWidgets(directory, cachedWidgetDescriptions, prototype=False, silent=False, addOn=None, defaultCategory=None, module=None): import sys global hasErrors, splashWindow, widgetsWithError, widgetsWithErrorPrototypes widgets = [] if not defaultCategory: predir, defaultCategory = os.path.split(directory.strip(os.path.sep).strip(os.path.altsep)) if defaultCategory == "widgets": defaultCategory = os.path.split(predir.strip(os.path.sep).strip(os.path.altsep))[1] if defaultCategory.lower() == "prototypes" or prototype: defaultCategory = "Prototypes" if module: files = [f for f in pkg_resources.resource_listdir(module.__name__, '') if f.endswith('.py')] else: files = glob.iglob(os.path.join(directory, "*.py")) for filename in files: if module: if pkg_resources.resource_isdir(module.__name__, filename): continue else: if os.path.isdir(filename): continue if module: if getattr(module, '__loader__', None): datetime = str(os.stat(module.__loader__.archive)[stat.ST_MTIME]) else: datetime = str(os.stat(pkg_resources.resource_filename(module.__name__, filename))[stat.ST_MTIME]) else: datetime = str(os.stat(filename)[stat.ST_MTIME]) cachedDescription = cachedWidgetDescriptions.get(filename, None) if cachedDescription and cachedDescription.time == datetime and hasattr(cachedDescription, "inputClasses"): widgets.append((cachedDescription.name, cachedDescription)) continue if module: data = pkg_resources.resource_string(module.__name__, filename) else: data = file(filename).read() try: meta = widgetParser.WidgetMetaData(data, defaultCategory, enforceDefaultCategory=prototype) except: # Probably not an Orange widget module. continue widgetPrototype = meta.prototype == "1" or meta.prototype.lower().strip() == "true" or prototype if widgetPrototype: meta.category = "Prototypes" dirname, fname = os.path.split(filename) widgname = os.path.splitext(fname)[0] try: if not splashWindow: import orngEnviron logo = QPixmap(os.path.join(orngEnviron.directoryNames["canvasDir"], "icons", "splash.png")) splashWindow = QSplashScreen(logo, Qt.WindowStaysOnTopHint) splashWindow.setMask(logo.mask()) splashWindow.show() splashWindow.showMessage("Registering widget %s" % meta.name, Qt.AlignHCenter + Qt.AlignBottom) qApp.processEvents() if module: import_name = "%s.%s" % (module.__name__, widgname) else: import_name = widgname wmod = __import__(import_name, fromlist=[""]) wmodFilename = wmod.__file__ if os.path.splitext(wmodFilename)[1] != "py": # Replace .pyc, .pyo with bare .py extension # (used as key in cachedWidgetDescription) wmodFilename = os.path.splitext(wmodFilename)[0] + ".py" # Evaluate the input/output list (all tuple items are strings) inputs = eval(meta.inputList) outputs = eval(meta.outputList) inputs = [InputSignal(*input) for input in inputs] outputs = [OutputSignal(*output) for output in outputs] # Resolve signal type names into concrete type instances inputs = [resolveSignal(input, globals=wmod.__dict__) for input in inputs] outputs = [resolveSignal(output, globals=wmod.__dict__) for output in outputs] inputClasses = set([s.type.__name__ for s in inputs]) outputClasses = set([klass.__name__ for s in outputs for klass in s.type.mro()]) # Convert all signal types back into qualified names. # This is to prevent any possible import problems when cached # descriptions are unpickled (the relevant code using this lists # should be able to handle missing types better). for s in inputs + outputs: s.type = "%s.%s" % (s.type.__module__, s.type.__name__) widgetInfo = WidgetDescription( name = meta.name, time = datetime, fileName = widgname, module = module.__name__ if module else None, fullName = wmodFilename, directory = directory, addOn = addOn, inputList = meta.inputList, outputList = meta.outputList, inputClasses = inputClasses, outputClasses = outputClasses, tags=meta.tags, inputs=inputs, outputs=outputs, ) for attr in ["contact", "icon", "priority", "description", "category"]: setattr(widgetInfo, attr, getattr(meta, attr)) # build the tooltip if len(widgetInfo.inputs) == 0: formatedInList = "<b>Inputs:</b><br> None<br>" else: formatedInList = "<b>Inputs:</b><br>" for signal in widgetInfo.inputs: formatedInList += " - " + signal.name + " (" + signal.type + ")<br>" if len(widgetInfo.outputs) == 0: formatedOutList = "<b>Outputs:</b><br> None<br>" else: formatedOutList = "<b>Outputs:</b><br>" for signal in widgetInfo.outputs: formatedOutList += " - " + signal.name + " (" + signal.type + ")<br>" addOnName = "" if not widgetInfo.addOn else " (from add-on %s)" % widgetInfo.addOn widgetInfo.tooltipText = "<b><b> %s</b></b>%s<hr><b>Description:</b><br> %s<hr>%s<hr>%s" % (meta.name, addOnName, widgetInfo.description, formatedInList[:-4], formatedOutList[:-4]) widgets.append((meta.name, widgetInfo)) except Exception, msg: if not hasErrors and not silent: print "There were problems importing the following widgets:" hasErrors = True if not silent: print " %s: %s" % (widgname, msg) if not widgetPrototype: widgetsWithError.append(widgname) else: widgetsWithErrorPrototypes.append(widgname)
def readWidgets(directory, cachedWidgetDescriptions, prototype=False, silent=False, addOn=None, defaultCategory=None, module=None): import sys global hasErrors, splashWindow, widgetsWithError, widgetsWithErrorPrototypes widgets = [] if not defaultCategory: predir, defaultCategory = os.path.split( directory.strip(os.path.sep).strip(os.path.altsep)) if defaultCategory == "widgets": defaultCategory = os.path.split( predir.strip(os.path.sep).strip(os.path.altsep))[1] if defaultCategory.lower() == "prototypes" or prototype: defaultCategory = "Prototypes" if module: files = [ f for f in pkg_resources.resource_listdir(module.__name__, '') if f.endswith('.py') ] else: files = glob.iglob(os.path.join(directory, "*.py")) for filename in files: if module: if pkg_resources.resource_isdir(module.__name__, filename): continue else: if os.path.isdir(filename): continue if module: if getattr(module, '__loader__', None): datetime = str( os.stat(module.__loader__.archive)[stat.ST_MTIME]) else: datetime = str( os.stat( pkg_resources.resource_filename( module.__name__, filename))[stat.ST_MTIME]) else: datetime = str(os.stat(filename)[stat.ST_MTIME]) cachedDescription = cachedWidgetDescriptions.get(filename, None) if cachedDescription and cachedDescription.time == datetime and hasattr( cachedDescription, "inputClasses"): widgets.append((cachedDescription.name, cachedDescription)) continue if module: data = pkg_resources.resource_string(module.__name__, filename) else: data = file(filename).read() try: meta = widgetParser.WidgetMetaData( data, defaultCategory, enforceDefaultCategory=prototype) except: # Probably not an Orange widget module. continue widgetPrototype = meta.prototype == "1" or meta.prototype.lower( ).strip() == "true" or prototype if widgetPrototype: meta.category = "Prototypes" dirname, fname = os.path.split(filename) widgname = os.path.splitext(fname)[0] try: if not splashWindow: import orngEnviron logo = QPixmap( os.path.join(orngEnviron.directoryNames["canvasDir"], "icons", "splash.png")) splashWindow = QSplashScreen(logo, Qt.WindowStaysOnTopHint) splashWindow.setMask(logo.mask()) splashWindow.show() splashWindow.showMessage("Registering widget %s" % meta.name, Qt.AlignHCenter + Qt.AlignBottom) qApp.processEvents() if module: import_name = "%s.%s" % (module.__name__, widgname) else: import_name = widgname wmod = __import__(import_name, fromlist=[""]) wmodFilename = wmod.__file__ if os.path.splitext(wmodFilename)[1] != "py": # Replace .pyc, .pyo with bare .py extension # (used as key in cachedWidgetDescription) wmodFilename = os.path.splitext(wmodFilename)[0] + ".py" # Evaluate the input/output list (all tuple items are strings) inputs = eval(meta.inputList) outputs = eval(meta.outputList) inputs = [InputSignal(*input) for input in inputs] outputs = [OutputSignal(*output) for output in outputs] # Resolve signal type names into concrete type instances inputs = [ resolveSignal(input, globals=wmod.__dict__) for input in inputs ] outputs = [ resolveSignal(output, globals=wmod.__dict__) for output in outputs ] inputClasses = set([s.type.__name__ for s in inputs]) outputClasses = set( [klass.__name__ for s in outputs for klass in s.type.mro()]) # Convert all signal types back into qualified names. # This is to prevent any possible import problems when cached # descriptions are unpickled (the relevant code using this lists # should be able to handle missing types better). for s in inputs + outputs: s.type = "%s.%s" % (s.type.__module__, s.type.__name__) widgetInfo = WidgetDescription( name=meta.name, time=datetime, fileName=widgname, module=module.__name__ if module else None, fullName=wmodFilename, directory=directory, addOn=addOn, inputList=meta.inputList, outputList=meta.outputList, inputClasses=inputClasses, outputClasses=outputClasses, tags=meta.tags, inputs=inputs, outputs=outputs, ) for attr in [ "contact", "icon", "priority", "description", "category" ]: setattr(widgetInfo, attr, getattr(meta, attr)) # build the tooltip if len(widgetInfo.inputs) == 0: formatedInList = "<b>Inputs:</b><br> None<br>" else: formatedInList = "<b>Inputs:</b><br>" for signal in widgetInfo.inputs: formatedInList += " - " + signal.name + " (" + signal.type + ")<br>" if len(widgetInfo.outputs) == 0: formatedOutList = "<b>Outputs:</b><br> None<br>" else: formatedOutList = "<b>Outputs:</b><br>" for signal in widgetInfo.outputs: formatedOutList += " - " + signal.name + " (" + signal.type + ")<br>" addOnName = "" if not widgetInfo.addOn else " (from add-on %s)" % widgetInfo.addOn widgetInfo.tooltipText = "<b><b> %s</b></b>%s<hr><b>Description:</b><br> %s<hr>%s<hr>%s" % ( meta.name, addOnName, widgetInfo.description, formatedInList[:-4], formatedOutList[:-4]) widgets.append((meta.name, widgetInfo)) except Exception, msg: if not hasErrors and not silent: print "There were problems importing the following widgets:" hasErrors = True if not silent: print " %s: %s" % (widgname, msg) if not widgetPrototype: widgetsWithError.append(widgname) else: widgetsWithErrorPrototypes.append(widgname)