2 # OK, this is more a proof of concept
5 # - screens need to be defined somehow else.
6 # I don't know how, yet. Probably each in an own file.
7 # - more components, like the channellist
8 # - better error handling
9 # - use namespace parser
11 from Screens.Screen import Screen
12 from Tools.Import import my_import
15 from Screens.InfoBarGenerics import InfoBarServiceName, InfoBarEvent
16 from Components.Sources.Clock import Clock
18 from xml.sax import make_parser
19 from xml.sax.handler import ContentHandler, feature_namespaces
20 from twisted.python import util
24 # prototype of the new web frontend template system.
27 class TestScreen(InfoBarServiceName, InfoBarEvent, Screen):
28 def __init__(self, session):
29 Screen.__init__(self, session)
30 InfoBarServiceName.__init__(self)
31 InfoBarEvent.__init__(self)
32 self["CurrentTime"] = Clock()
34 # turns .text into __str__
36 def __init__(self, source):
40 return self.source.text
42 # a to-be-filled list item
44 def __init__(self, name):
47 # the performant 'listfiller'-engine (plfe)
48 class ListFiller(object):
49 def __init__(self, arg):
56 # now build a ["string", 1, "string", 2]-styled list, with indices into the
57 # list to avoid lookup of item name for each entry
59 for element in self.template:
60 if isinstance(element, str):
61 lutlist.append(element)
62 elif isinstance(element, ListItem):
63 lutlist.append(lut[element.name])
65 # now, for the huge list, do:
68 for element in lutlist:
69 if isinstance(element, str):
72 res += str(item[element])
73 # (this will be done in c++ later!)
76 text = property(getText)
78 class webifHandler(ContentHandler):
79 def __init__(self, session):
83 self.session = session
85 def startElement(self, name, attrs):
86 if name == "e2:screen":
87 self.screen = eval(attrs["name"])(self.session) # fixme
93 tag = "<" + name + ''.join([' ' + key + '="' + val + '"' for (key, val) in attrs.items()]) + ">"
94 tag = tag.encode("UTF-8")
98 elif self.mode == 1: # expect "<e2:element>"
99 assert name == "e2:element", "found %s instead of e2:element" % name
100 self.source = self.screen[attrs["source"]]
101 elif self.mode == 2: # expect "<e2:convert>"
102 if name[:3] == "e2:":
103 assert name == "e2:convert"
105 ctype = attrs["type"]
106 if ctype[:4] == "web:": # for now
107 self.converter = eval(ctype[4:])
109 self.converter = my_import('.'.join(["Components", "Converter", ctype])).__dict__.get(ctype)
114 assert name == "e2:item", "found %s instead of e2:item!" % name
115 self.sub.append(ListItem(attrs["name"]))
117 def endElement(self, name):
118 if name == "e2:screen":
122 tag = "</" + name + ">"
125 elif self.mode == 2 and name[:3] != "e2:":
127 elif self.mode == 2: # closed 'convert' -> sub
128 self.sub = lreduce(self.sub)
129 if len(self.sub) == 1:
130 self.sub = self.sub[0]
131 c = self.converter(self.sub)
132 c.connect(self.source)
136 elif self.mode == 1: # closed 'element'
137 self.res.append(Element(self.source))
140 if name[:3] == "e2:":
143 def processingInstruction(self, target, data):
144 self.res.append('<?' + target + ' ' + data + '>')
146 def characters(self, ch):
147 ch = ch.encode("UTF-8")
153 def startEntity(self, name):
154 self.res.append('&' + name + ';');
157 # ouch, can be made better
161 if isinstance(x, str) or isinstance(x, unicode):
162 x = x.encode("UTF-8")
168 if string is not None:
172 if string is not None:
177 def renderPage(stream, req, session):
178 handler = webifHandler(session)
179 parser = make_parser()
180 parser.setFeature(feature_namespaces, 0)
181 parser.setContentHandler(handler)
182 parser.parse(open(util.sibpath(__file__, 'test.xml'))) # currently fixed
183 for x in lreduce(handler.res):
185 stream.finish() # must be done, unless we "callLater"