1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
#
# OK, this is more a proof of concept
# things to improve:
# - nicer code
# - screens need to be defined somehow else.
# I don't know how, yet. Probably each in an own file.
# - more components, like the channellist
# - better error handling
# - use namespace parser
from Screens.Screen import Screen
from Tools.Import import my_import
# for our testscreen
from Screens.InfoBarGenerics import InfoBarServiceName, InfoBarEvent
from Components.Sources.Clock import Clock
from xml.sax import make_parser
from xml.sax.handler import ContentHandler, feature_namespaces
from twisted.python import util
import sys
import time
# prototype of the new web frontend template system.
# a test screen
class TestScreen(InfoBarServiceName, InfoBarEvent, Screen):
def __init__(self, session):
Screen.__init__(self, session)
InfoBarServiceName.__init__(self)
InfoBarEvent.__init__(self)
self["CurrentTime"] = Clock()
# turns .text into __str__
class Element:
def __init__(self, source):
self.source = source
def __str__(self):
return self.source.text
# a to-be-filled list item
class ListItem:
def __init__(self, name):
self.name = name
# the performant 'listfiller'-engine (plfe)
class ListFiller(object):
def __init__(self, arg):
self.template = arg
def getText(self):
l = self.source.list
lut = self.source.lut
# now build a ["string", 1, "string", 2]-styled list, with indices into the
# list to avoid lookup of item name for each entry
lutlist = []
for element in self.template:
if isinstance(element, str):
lutlist.append(element)
elif isinstance(element, ListItem):
lutlist.append(lut[element.name])
# now, for the huge list, do:
res = ""
for item in l:
for element in lutlist:
if isinstance(element, str):
res += element
else:
res += str(item[element])
# (this will be done in c++ later!)
return res
text = property(getText)
class webifHandler(ContentHandler):
def __init__(self, session):
self.res = [ ]
self.mode = 0
self.screen = None
self.session = session
def startElement(self, name, attrs):
if name == "e2:screen":
self.screen = eval(attrs["name"])(self.session) # fixme
return
if name[:3] == "e2:":
self.mode += 1
tag = "<" + name + ''.join([' ' + key + '="' + val + '"' for (key, val) in attrs.items()]) + ">"
tag = tag.encode("UTF-8")
if self.mode == 0:
self.res.append(tag)
elif self.mode == 1: # expect "<e2:element>"
assert name == "e2:element", "found %s instead of e2:element" % name
self.source = self.screen[attrs["source"]]
elif self.mode == 2: # expect "<e2:convert>"
if name[:3] == "e2:":
assert name == "e2:convert"
ctype = attrs["type"]
if ctype[:4] == "web:": # for now
self.converter = eval(ctype[4:])
else:
self.converter = my_import('.'.join(["Components", "Converter", ctype])).__dict__.get(ctype)
self.sub = [ ]
else:
self.sub.append(tag)
elif self.mode == 3:
assert name == "e2:item", "found %s instead of e2:item!" % name
self.sub.append(ListItem(attrs["name"]))
def endElement(self, name):
if name == "e2:screen":
self.screen = None
return
tag = "</" + name + ">"
if self.mode == 0:
self.res.append(tag)
elif self.mode == 2 and name[:3] != "e2:":
self.sub.append(tag)
elif self.mode == 2: # closed 'convert' -> sub
self.sub = lreduce(self.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
elif self.mode == 1: # closed 'element'
self.res.append(Element(self.source))
del self.source
if name[:3] == "e2:":
self.mode -= 1
def processingInstruction(self, target, data):
self.res.append('<?' + target + ' ' + data + '>')
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 + ';');
def lreduce(list):
# ouch, can be made better
res = [ ]
string = None
for x in list:
if isinstance(x, str) or isinstance(x, unicode):
x = x.encode("UTF-8")
if string is None:
string = x
else:
string += x
else:
if string is not None:
res.append(string)
string = None
res.append(x)
if string is not None:
res.append(string)
string = None
return res
def renderPage(stream, path, session):
handler = webifHandler(session)
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
parser.setContentHandler(handler)
parser.parse(open(util.sibpath(__file__, path)))
for x in lreduce(handler.res):
stream.write(str(x))
stream.finish() # must be done, unless we "callLater"
|