OLD | NEW |
| (Empty) |
1 from __future__ import nested_scopes | |
2 | |
3 from types import ClassType | |
4 | |
5 from twisted.web import server | |
6 from twisted.web import util as webutil | |
7 from twisted.web.woven import interfaces | |
8 from twisted.python import failure, log, components | |
9 from zope.interface import implements | |
10 | |
11 def renderFailure(fail, request): | |
12 if not fail: | |
13 fail = failure.Failure() | |
14 log.err(fail) | |
15 request.write(webutil.formatFailure(fail)) | |
16 #request.finish() | |
17 | |
18 | |
19 def doSendPage(self, d, request): | |
20 page = str(d.toprettyxml()) | |
21 request.setHeader('content-length', str(len(page))) | |
22 request.write(page) | |
23 request.finish() | |
24 return page | |
25 | |
26 | |
27 class Script: | |
28 type="javascript1.2" | |
29 def __init__(self, script): | |
30 self.script = script | |
31 | |
32 | |
33 class WovenLivePage: | |
34 implements(interfaces.IWovenLivePage) | |
35 | |
36 currentPage = None | |
37 def __init__(self, session): | |
38 self.session = session | |
39 self.output = None | |
40 self.input = None | |
41 self.cached = [] | |
42 self.inputCache = [] | |
43 | |
44 def getCurrentPage(self): | |
45 """Return the current page object contained in this session. | |
46 """ | |
47 return self.currentPage | |
48 | |
49 def setCurrentPage(self, page): | |
50 """Set the current page object contained in this session. | |
51 """ | |
52 self.currentPage = page | |
53 | |
54 def write(self, text): | |
55 """Write "text" to the live page's persistent output conduit. | |
56 If there is no conduit connected yet, save the text and write it | |
57 as soon as the output conduit is connected. | |
58 """ | |
59 if self.output is None: | |
60 self.cached.append(text) | |
61 print "CACHING", `self.cached` | |
62 else: | |
63 if isinstance(text, Script): | |
64 if hasattr(self.output, 'writeScript'): | |
65 self.output.writeScript(text.script) | |
66 return | |
67 text = '<script language="%s">%s</script>\r\n' % (text.type, tex
t.script) | |
68 print "WRITING", text | |
69 if text[-1] != '\n': | |
70 text += '\n' | |
71 self.output.write(text) | |
72 | |
73 def sendScript(self, js): | |
74 self.write(Script(js)) | |
75 if self.output is not None and not getattr(self.output, 'keepalive', Non
e): | |
76 print "## woot, teh connection was open" | |
77 ## Close the connection; the javascript will have to open it again t
o get the next event. | |
78 self.output.finish() | |
79 self.output = None | |
80 | |
81 def hookupOutputConduit(self, request): | |
82 """Hook up the given request as the output conduit for this | |
83 session. | |
84 """ | |
85 print "TOOT! WE HOOKED UP OUTPUT!", `self.cached` | |
86 self.output = request | |
87 for text in self.cached: | |
88 self.write(text) | |
89 if self.cached: | |
90 self.cached = [] | |
91 if not getattr(self.output, 'keepalive', None): | |
92 ## Close the connection; the javascript will have to open it aga
in to get the next event. | |
93 request.finish() | |
94 self.output = None | |
95 | |
96 def unhookOutputConduit(self): | |
97 self.output = None | |
98 | |
99 def hookupInputConduit(self, obj): | |
100 """Hook up the given object as the input conduit for this | |
101 session. | |
102 """ | |
103 print "HOOKING UP", self.inputCache | |
104 self.input = obj | |
105 for text in self.inputCache: | |
106 self.pushThroughInputConduit(text) | |
107 self.inputCache = [] | |
108 print "DONE HOOKING", self.inputCache | |
109 | |
110 def pushThroughInputConduit(self, inp): | |
111 """Push some text through the input conduit. | |
112 """ | |
113 print "PUSHING INPUT", inp | |
114 if self.input is None: | |
115 self.inputCache.append(inp) | |
116 else: | |
117 self.input(inp) | |
118 | |
119 class Stack: | |
120 def __init__(self, stack=None): | |
121 if stack is None: | |
122 self.stack = [] | |
123 else: | |
124 self.stack = stack | |
125 | |
126 def push(self, item): | |
127 self.stack.insert(0, item) | |
128 | |
129 def pop(self): | |
130 if self.stack: | |
131 return self.stack.pop(0) | |
132 | |
133 def peek(self): | |
134 for x in self.stack: | |
135 if x is not None: | |
136 return x | |
137 | |
138 def poke(self, item): | |
139 self.stack[0] = item | |
140 | |
141 def clone(self): | |
142 return Stack(self.stack[:]) | |
143 | |
144 def __len__(self): | |
145 return len(self.stack) | |
146 | |
147 def __getitem__(self, item): | |
148 return self.stack[item] | |
149 | |
150 | |
151 class GetFunction: | |
152 def __init__(self, namespace): | |
153 self.namespace = namespace | |
154 | |
155 def __call__(self, request, node, model, viewName): | |
156 """Get a name from my namespace. | |
157 """ | |
158 from twisted.web.woven import widgets | |
159 if viewName == "None": | |
160 return widgets.DefaultWidget(model) | |
161 | |
162 vc = getattr(self.namespace, viewName, None) | |
163 # don't call modules and random crap in the namespace, only widgets | |
164 if vc and isinstance(vc, (type, ClassType)) and issubclass(vc, widgets.W
idget): | |
165 return vc(model) | |
166 | |
167 | |
168 def createGetFunction(namespace): | |
169 return GetFunction(namespace) | |
170 | |
171 | |
172 class SetId: | |
173 def __init__(self, theId): | |
174 self.theId = theId | |
175 | |
176 def __call__(self, request, wid, data): | |
177 id = wid.attributes.get('id', None) | |
178 if not id: | |
179 wid.setAttribute('id', self.theId) | |
180 else: | |
181 top = wid | |
182 while getattr(top, 'parent', None) is not None: | |
183 top = top.parent | |
184 if top.subviews.has_key(self.theId): | |
185 del top.subviews[self.theId] | |
186 top.subviews[id] = wid | |
187 if wid.parent.subviews.has_key(self.theId): | |
188 del wid.parent.subviews[self.theId] | |
189 wid.parent.subviews[id] = wid | |
190 | |
191 | |
192 def createSetIdFunction(theId): | |
193 return SetId(theId) | |
194 | |
195 | |
196 | |
197 components.registerAdapter(WovenLivePage, server.Session, interfaces.IWovenLiveP
age) | |
198 | |
OLD | NEW |