rendered paste bodyIndex: examples.tac
===================================================================
--- examples.tac (revision 12985)
+++ examples.tac (working copy)
@@ -54,7 +54,6 @@
from nestedsequence import nestedsequence
from fragments import fragments
from macros import macros
- from chatola import chatola
from i18n import i18n, xmli18n
from cal import cal
from tabbed import tabbed
@@ -66,6 +65,7 @@
from athenademo import typeahead
from athenademo import widgets
from athenademo import benchmark
+ from athenademo import chatola
except ImportError, e:
if str(e).find('No module named') != -1:
msg = """
@@ -152,7 +152,6 @@
xul_nevow=xul_nevow.createResource(),
advanced_manualform=advanced_manualform.Page(),
liveanimal=liveanimal.createResource(),
- chatola=chatola.createResource(),
http_auth=http_auth.AuthorizationRequired(),
most_basic=most_basic.root,
logout_guard=logout_guard.createResource(),
@@ -172,7 +171,7 @@
formless_tests=testformless.formless_tests,
fragments=fragments.Root(),
macros=macros.Root(),
- typeahead=typeahead.DataEntry(),
+ typeahead=typeahead.DataEntry(),
)
def child_calculator(self, ctx):
@@ -181,6 +180,9 @@
def child_widgets(self, ctx):
return widgets.WidgetPage(None, None)
+ def child_chatola(self, ctx):
+ return chatola.ChatolaPage(None, None)
+
def child_benchmark(self, ctx):
return benchmark.Benchmark(400, 20)
chatola.py:
from twisted.python import util
from twisted.internet import reactor
from nevow import athena, loaders, static, inevow
class TheRoom:
"""Holds information about the chat room."""
topic = u"Topic is not set yet."
clients = []
theRoom = TheRoom()
class ChatElement(athena.LiveElement):
"""I am a chatting element."""
jsClass = u"Chatola.Chat"
docFactory = loaders.xmlfile(util.sibpath(
__file__, "chatola.html"))
nickname = u"guest"
room = theRoom
def disconnect(self, reason):
"""This client left the chat room."""
self.room.clients.remove(self)
self.sendEvent(u"*** %s left." % self.nickname)
def join(self):
"""Client-side informs the element that it has joined the
room."""
self.room.clients.append(self)
self.sendEvent(u"*** %s joined." % self.nickname)
# set topic
reactor.callLater(
0, self.callRemote, 'setTopic', self.room.topic)
# remove client if it disconnects
d = self.page.notifyOnDisconnect()
d.addErrback(self.disconnect)
athena.expose(join)
def setNickname(self, nickname):
"""Set nickname of the chatter."""
self.sendEvent(u"*** %s changed nickname to %s" % (
self.nickname, nickname))
self.nickname = nickname
athena.expose(setNickname)
def setTopic(self, newTopic):
"""Set topic."""
self.room.topic = newTopic
self.sendEvent(u"*** %s changed topic to %s" % (
self.nickname, newTopic))
self.sendCall('setTopic', newTopic)
athena.expose(setTopic)
def sayLine(self, line):
if not line:
return
self.sendEvent(u"<%s> %s" % (self.nickname, line))
athena.expose(sayLine)
def sendEvent(self, event):
"""Send event to all clients."""
self.sendCall('publish', unicode(event))
def sendCall(self, function, *args):
for client in self.room.clients:
client.callRemote(function, *args)
class ChatolaPage(athena.LivePage):
docFactory = loaders.xmlstr("""\
<html xmlns:nevow="http://nevow.com/ns/nevow/0.1">
<head>
<link rel="stylesheet" type="text/css" href="/chatola/css" />
<nevow:invisible nevow:render="liveglue" />
</head>
<body>
<div nevow:render="chat" />
</body>
</html>
""")
addSlash = True
child_css = static.File(util.sibpath(
__file__, 'chatola.css'))
def __init__(self, *a, **kw):
super(ChatolaPage, self).__init__(*a, **kw)
self.jsModules.mapping[u'Chatola'] = util.sibpath(
__file__, 'chatola.js')
self.clients = []
def render_chat(self, ctx, data):
e = ChatElement()
e.setFragmentParent(self)
return e
chatola.js:
// import Nevow.Athena
Chatola.Chat = Nevow.Athena.Widget.subclass('Chatola.Chat');
Chatola.Chat.methods(
function __init__(self, node) {
Chatola.Chat.upcall(self, '__init__', node);
self.callRemote('join');
},
function publish(self, event) {
var br = document.createElement('br');
var tt = document.createElement('tt');
tt.appendChild(document.createTextNode(event));
var node = self.nodeById("events");
node.appendChild(tt);
node.appendChild(br);
},
function setTopic(self, topic) {
var node = self.nodeById("topic");
node.value = topic;
},
function nickChanged(self, event, data) {
var node = self.nodeById("nick");
self.callRemote('setNickname', node.value);
},
function topicChanged(self, event, data) {
var node = self.nodeById("topic");
self.callRemote('setTopic', node.value);
},
function lineEntered(self, event, data) {
var node = self.nodeById("line");
self.callRemote('sayLine', node.value);
node.value = "";
}
);
chatola.html:
<div xmlns:nevow="http://nevow.com/ns/nevow/0.1"
xmlns:athena="http://divmod.org/ns/athena/0.7">
<table width="100" nevow:render="liveElement" border="0">
<tr>
<td width="100%">
<input type="text" size="125" id="topic">
<athena:handler event="onchange" handler="topicChanged" />
</input>
</td>
</tr>
<tr height="100%" width="100%">
<td id="events" />
</tr>
<tr>
<td>
Nick:
<input type="text" size="5" id="nick" value="guest">
<athena:handler event="onchange" handler="nickChanged" />
</input>
say:
<input type="text" size="105" id="line">
<athena:handler event="onchange" handler="lineEntered" />
</input>
</td>
</tr>
</table>
</div>
chatola.css:
table {
table-layout: fixed;
width: 800px;
}