source: orange/Orange/utils/widgetparser.py @ 10581:94a831b04ec3

Revision 10581:94a831b04ec3, 3.4 KB checked in by markotoplak, 2 years ago (diff)

Moved some other scripts from misc to utils and Orange imports and canvas not works, although not systematically tested.

Line 
1import xml.dom.minidom
2import re, os
3from fileutil import xml_text_of
4from fileutil import create_text_element
5from fileutil import _zip_open
6
7re_inputs = re.compile(r'[ \t]+self.inputs\s*=\s*(?P<signals>\[[^]]*\])', re.DOTALL)
8re_outputs = re.compile(r'[ \t]+self.outputs\s*=\s*(?P<signals>\[[^]]*\])', re.DOTALL)
9re_tuple = re.compile(r"\(([^)]+)\)")
10
11def _getSignalList(regex, data):
12    inmo = regex.search(data)
13    if inmo:
14        return str([tuple([y[0] in "'\"" and y[1:-1] or str(y) for y in (x.strip() for x in ttext.group(1).split(","))])
15                    for ttext in re_tuple.finditer(inmo.group("signals"))])
16    else:
17        return "[]"
18
19class WidgetMetaData:
20    xmlAttrs = ["name", "description", "contact", "category", "icon", "hasDoc"]
21
22    def __init__(self, data, defaultCategory="Prototypes", enforceDefaultCategory=False, filename=None, hasDoc="0"):  # data can either be a string with module (.py file) contents or an xml.dom.Element
23        if not filename and data.__class__ is xml.dom.minidom.Element:  # XML (as returned by toXml())
24            self.name=""
25            self.icon=""
26            self.priority=""
27            self.description=""
28            self.category=""
29            self.tags=""
30            self.filename=None
31            self.hasDoc = hasDoc
32            for attr in self.xmlAttrs:
33                nodes = data.getElementsByTagName(attr)
34                if nodes:
35                    setattr(self, attr, xml_text_of(nodes[0]))
36            if data.hasAttribute("filename"):
37                self.filename = data.getAttribute("filename")
38        else:   # python module
39            setattr(self, "filename", filename)
40            for attr, deflt in (("name", None), ("contact", "") , ("icon", "icons/Unknown.png"), ("priority", "5000"), ("description", ""), ("category", defaultCategory), ("tags", "")):
41                istart, iend = data.find("<"+attr+">"), data.find("</"+attr+">")
42                setattr(self, attr, istart >= 0 and iend >= 0 and data[istart+2+len(attr):iend].strip() or deflt)
43            if enforceDefaultCategory:
44                self.category = defaultCategory
45            if not self.name:
46                raise Exception("Not an Orange widget module.")
47            self.hasDoc = hasDoc
48            self.inputList = _getSignalList(re_inputs, data)
49            self.outputList = _getSignalList(re_outputs, data)
50
51    def clone(self):
52        return WidgetMetaData(self.toXml())
53
54    def toXml(self):
55        widgetTag = xml.dom.minidom.Element("widget")
56        for attr in self.xmlAttrs:
57            if hasattr(self, attr):
58                widgetTag.appendChild(create_text_element(attr, getattr(self, attr)))
59        if "filename" in self.__dict__ and self.filename:
60            widgetTag.setAttribute("filename", self.filename)
61        return widgetTag
62
63_widgetModuleName = re.compile(r"widgets/(prototypes/|)[^/]*\.py$")
64def widgetsXml(oaoZip):
65    files = oaoZip.namelist()
66    widgetsTag = xml.dom.minidom.Element("widgets")
67    for file in files:
68        if re.match(_widgetModuleName, file):
69            try:
70                filename = file[8:]
71                meta = WidgetMetaData(_zip_open(oaoZip, file).read(), "None", filename=filename, hasDoc="1" if ("doc/widgets/%s.htm" % (os.path.splitext(filename)[0][2:]) in files) else "0")
72            except:
73                continue   # Probably not an Orange widget module
74            widgetsTag.appendChild(meta.toXml())
75    return widgetsTag
Note: See TracBrowser for help on using the repository browser.