From 338e00d2833fc5883ebf87f7e8ec86f7bf55e3c2 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Thu, 29 Nov 2007 12:31:59 +0000 Subject: [PATCH] re-arrange code a bit for reusability, add 'MacroElements' which can be used to import the output of elements into lists --- webinterface/src/webif.py | 190 +++++++++++++++++++++++--------------- 1 file changed, 117 insertions(+), 73 deletions(-) diff --git a/webinterface/src/webif.py b/webinterface/src/webif.py index d95f75e3..93d2192c 100644 --- a/webinterface/src/webif.py +++ b/webinterface/src/webif.py @@ -283,26 +283,35 @@ class OneTimeElement(Element): else: for c in args.get(self.source_id, []): self.source.handleCommand(c) - + def render(self, stream): t = self.source.getHTML(self.source_id) stream.write(t) def execBegin(self): pass - + def execEnd(self): pass - + def onShow(self): pass def onHide(self): pass - + def destroy(self): pass +class MacroElement(OneTimeElement): + def __init__(self, id, macro_dict, macro_name): + OneTimeElement.__init__(self, id) + self.macro_dict = macro_dict + self.macro_name = macro_name + + def render(self, stream): + self.macro_dict[self.macro_name] = self.source.getHTML(self.source_id) + class StreamingElement(OneTimeElement): def __init__(self, id): OneTimeElement.__init__(self, id) @@ -320,7 +329,12 @@ class ListItem: def __init__(self, name, filternum): self.name = name self.filternum = filternum - + +class ListMacroItem: + def __init__(self, macrodict, macroname): + self.macrodict = macrodict + self.macroname = macroname + class TextToHTML(Converter): def __init__(self, arg): Converter.__init__(self, arg) @@ -338,7 +352,7 @@ class TextToURL(Converter): class ReturnEmptyXML(Converter): def __init__(self, arg): Converter.__init__(self, arg) - + def getHTML(self, id): return "" @@ -372,7 +386,16 @@ class ListFiller(Converter): # now build a ["string", 1, "string", 2]-styled list, with indices into the # list to avoid lookup of item name for each entry - lutlist = [ isinstance(element, basestring) and (element, None) or (lut[element.name], element.filternum) for element in conv_args ] + lutlist = [ ] + for element in conv_args: + if isinstance(element, basestring): + lutlist.append((element, None)) + elif isinstance(element, ListItem): + lutlist.append((lut[element.name], element.filternum)) + elif isinstance(element, ListMacroItem): + lutlist.append((element.macrodict[element.macroname], None)) + else: + raise "neither string, ListItem nor ListMacroItem" # now, for the huge list, do: strlist = [ ] @@ -402,13 +425,91 @@ class webifHandler(ContentHandler): self.session = session self.screens = [ ] self.request = request - + self.macros = { } + + def start_element(self, attrs): + scr = self.screen + + wsource = attrs["source"] + + path = wsource.split('.') + while len(path) > 1: + scr = self.screen.getRelatedScreen(path[0]) + if scr is None: + print "[webif.py] Parent Screen not found!" + print wsource + path = path[1:] + + source = scr.get(path[0]) + + if isinstance(source, ObsoleteSource): + # however, if we found an "obsolete source", issue warning, and resolve the real source. + print "WARNING: WEBIF '%s' USES OBSOLETE SOURCE '%s', USE '%s' INSTEAD!" % (name, wsource, source.new_source) + print "OBSOLETE SOURCE WILL BE REMOVED %s, PLEASE UPDATE!" % (source.removal_date) + if source.description: + print source.description + + wsource = source.new_source + else: + pass + # otherwise, use that source. + + self.source = source + self.source_id = str(attrs.get("id", wsource)) + self.is_streaming = "streaming" in attrs + self.macro_name = attrs.get("macro") or None + + def end_element(self): + # instatiate either a StreamingElement or a OneTimeElement, depending on what's required. + if not self.is_streaming: + if self.macro_name is None: + c = OneTimeElement(self.source_id) + else: + c = MacroElement(self.source_id, self.macros, self.macro_name) + else: + assert self.macro_name is None + c = StreamingElement(self.source_id) + + c.connect(self.source) + self.res.append(c) + self.screen.renderer.append(c) + del self.source + + def start_convert(self, attrs): + ctype = attrs["type"] + + # TODO: we need something better here + if ctype[:4] == "web:": # for now + self.converter = eval(ctype[4:]) + else: + try: + self.converter = my_import('.'.join(["Components", "Converter", ctype])).__dict__.get(ctype) + except ImportError: + self.converter = my_import('.'.join(["Plugins", "Extensions", "WebInterface", "WebComponents", "Converter", ctype])).__dict__.get(ctype) + self.sub = [ ] + + def end_convert(self): + if len(self.sub) == 1: + self.sub = self.sub[0] + c = self.converter(self.sub) + c.connect(self.source) + self.source = c + del self.sub + + def parse_item(self, attrs): + if "name" in attrs: + filter = {"": 1, "javascript_escape": 2, "xml": 3, "uri": 4}[attrs.get("filter", "")] + self.sub.append(ListItem(attrs["name"], filter)) + else: + assert "macro" in attrs, "e2:item must have a name= or macro= attribute!" + self.sub.append(ListMacroItem(self.macros, attrs["macro"])) + def startElement(self, name, attrs): if name == "e2:screen": self.screen = eval(attrs["name"])(self.session,self.request) # fixme self.screens.append(self.screen) return - + if name[:3] == "e2:": self.mode += 1 @@ -421,59 +522,17 @@ class webifHandler(ContentHandler): if self.mode == 0: self.res.append(tag) elif self.mode == 1: # expect "" - scr = self.screen - assert name == "e2:element", "found %s instead of e2:element" % name - wsource = attrs["source"] - - path = wsource.split('.') - while len(path) > 1: - scr = self.screen.getRelatedScreen(path[0]) - if scr is None: - print "[webif.py] Parent Screen not found!" - print wsource - path = path[1:] - - source = scr.get(path[0]) - - if isinstance(source, ObsoleteSource): - # however, if we found an "obsolete source", issue warning, and resolve the real source. - print "WARNING: WEBIF '%s' USES OBSOLETE SOURCE '%s', USE '%s' INSTEAD!" % (name, wsource, source.new_source) - print "OBSOLETE SOURCE WILL BE REMOVED %s, PLEASE UPDATE!" % (source.removal_date) - if source.description: - print source.description - - wsource = source.new_source - else: - pass - # otherwise, use that source. - - self.source = source - self.source_id = str(attrs.get("id", wsource)) - self.is_streaming = "streaming" in attrs - + self.start_element(attrs) elif self.mode == 2: # expect "" if name[:3] == "e2:": assert name == "e2:convert" - - ctype = attrs["type"] - - # TODO: we need something better here - if ctype[:4] == "web:": # for now - self.converter = eval(ctype[4:]) - else: - try: - self.converter = my_import('.'.join(["Components", "Converter", ctype])).__dict__.get(ctype) - except ImportError: - self.converter = my_import('.'.join(["Plugins", "Extensions", "WebInterface", "WebComponents", "Converter", ctype])).__dict__.get(ctype) - self.sub = [ ] + self.start_convert(attrs) else: self.sub.append(tag) elif self.mode == 3: assert name == "e2:item", "found %s instead of e2:item!" % name - assert "name" in attrs, "e2:item must have a name= attribute!" - filter = {"": 1, "javascript_escape": 2, "xml": 3, "uri": 4}[attrs.get("filter", "")] - self.sub.append(ListItem(attrs["name"], filter)) + self.parse_item(attrs) def endElement(self, name): if name == "e2:screen": @@ -486,37 +545,22 @@ class webifHandler(ContentHandler): elif self.mode == 2 and name[:3] != "e2:": self.sub.append(tag) elif self.mode == 2: # closed 'convert' -> sub - if len(self.sub) == 1: - self.sub = self.sub[0] - c = self.converter(self.sub) - c.connect(self.source) - self.source = c - del self.sub + self.end_convert() elif self.mode == 1: # closed 'element' - # instatiate either a StreamingElement or a OneTimeElement, depending on what's required. - if not self.is_streaming: - c = OneTimeElement(self.source_id) - else: - c = StreamingElement(self.source_id) - - c.connect(self.source) - self.res.append(c) - self.screen.renderer.append(c) - del self.source - + self.end_element() if name[:3] == "e2:": self.mode -= 1 def processingInstruction(self, target, data): self.res.append('') - + def characters(self, ch): ch = ch.encode('utf-8') if self.mode == 0: self.res.append(ch) elif self.mode == 2: self.sub.append(ch) - + def startEntity(self, name): self.res.append('&' + name + ';'); -- 2.20.1