All pastes #616890 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-07-12 22:09 UTC
rendered paste body
Index: 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;
}