Ignore:
Timestamp:
04/20/12 03:15:24 (2 years ago)
Author:
mitar
Branch:
default
Message:

Support for widgets loading from modules, registered through entry point.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/orngRegistry.py

    r10824 r10827  
    33 
    44import os, sys, re, glob, stat 
     5import pkg_resources 
    56from orngSignalManager import OutputSignal, InputSignal, resolveSignal 
    67from PyQt4.QtCore import * 
     
    1314 
    1415import orngEnviron, Orange.utils.addons 
    15  
    16 class WidgetDescription: 
     16from Orange.utils import addons 
     17 
     18WIDGETS_ENTRY_POINT = 'orange.widgets' 
     19 
     20class WidgetDescription(object): 
    1721    def __init__(self, **attrs): 
    1822        self.__dict__.update(attrs) 
     
    7074        directory = os.path.join(widgetDirName, dirName) 
    7175        if os.path.isdir(directory): 
    72             directories.append((None, directory, None, "prototypes" in dirName.lower())) 
     76            directories.append((None, directory, None, "prototypes" in dirName.lower(), None)) 
    7377             
    7478    # read list of add-ons 
     
    7680        addOnWidgetsDir = os.path.join(addOn.directory, "widgets") 
    7781        if os.path.isdir(addOnWidgetsDir): 
    78             directories.append((addOn.name, addOnWidgetsDir, addOn, False)) 
     82            directories.append((addOn.name, addOnWidgetsDir, addOn, False, None)) 
    7983        addOnWidgetsPrototypesDir = os.path.join(addOnWidgetsDir, "prototypes") 
    8084        if os.path.isdir(addOnWidgetsPrototypesDir): 
    81             directories.append((None, addOnWidgetsPrototypesDir, addOn, True)) 
     85            directories.append((None, addOnWidgetsPrototypesDir, addOn, True, None)) 
     86 
     87    # New-type add-ons 
     88    for entry_point in pkg_resources.iter_entry_points(WIDGETS_ENTRY_POINT): 
     89        try: 
     90            module = entry_point.load() 
     91            if hasattr(module, '__path__'): 
     92                # It is a package 
     93                addOn = addons.OrangeAddOn() 
     94                addOn.name = entry_point.name 
     95                addOn.directory = module.__path__[0] # This is invalid and useless as documentation is not there, but to set it to something 
     96                directories.append((entry_point.name, module.__path__[0], addOn, False, module.__name__)) 
     97            else: 
     98                # It is a module 
     99                # TODO: Implement loading of widget modules 
     100                # (This should be default way to load widgets, not parsing them as files, or traversing directories, just modules and packages (which load modules)) 
     101                pass 
     102        except ImportError, err: 
     103            print "While loading, importing widgets '%s' failed: %s" % (entry_point.name, err) 
    82104 
    83105    categories = {}      
    84     for defCat, dirName, addOn, isPrototype in directories: 
    85         widgets = readWidgets(dirName, cachedWidgetDescriptions, isPrototype, silent=silent, addOn=addOn, defaultCategory=defCat) 
     106    for defCat, dirName, addOn, isPrototype, module in directories: 
     107        widgets = readWidgets(dirName, cachedWidgetDescriptions, isPrototype, silent=silent, addOn=addOn, defaultCategory=defCat, module=module) 
    86108        for (wName, wInfo) in widgets: 
    87109            catName = wInfo.category 
     
    113135widgetsWithErrorPrototypes = [] 
    114136 
    115 def readWidgets(directory, cachedWidgetDescriptions, prototype=False, silent=False, addOn=None, defaultCategory=None): 
     137def readWidgets(directory, cachedWidgetDescriptions, prototype=False, silent=False, addOn=None, defaultCategory=None, module=None): 
    116138    import sys, imp 
    117139    global hasErrors, splashWindow, widgetsWithError, widgetsWithErrorPrototypes 
     
    142164        except:   # Probably not an Orange widget module. 
    143165            continue 
     166 
     167        widgetPrototype = meta.prototype == "1" or meta.prototype.lower().strip() == "true" or prototype 
     168        if widgetPrototype: 
     169            meta.category = "Prototypes" 
    144170 
    145171        dirname, fname = os.path.split(filename) 
     
    162188            if not dirnameInPath: 
    163189                sys.path.append(dirname) 
    164             wmod = imp.load_source(widgname, filename) 
     190            if module: 
     191                wmod = imp.load_source("%s.%s" % (module, widgname), filename) 
     192            else: 
     193                wmod = imp.load_source(widgname, filename) 
    165194            if not dirnameInPath and dirname in sys.path: # I have no idea, why we need this, but it seems to disappear sometimes?! 
    166195                sys.path.remove(dirname) 
     
    195224                             time = datetime, 
    196225                             fileName = widgname, 
     226                             module = module, 
    197227                             fullName = filename, 
    198228                             directory = directory, 
     
    234264                print "   %s: %s" % (widgname, msg) 
    235265 
    236             if not prototype: 
     266            if not widgetPrototype: 
    237267                widgetsWithError.append(widgname) 
    238268            else: 
Note: See TracChangeset for help on using the changeset viewer.