~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/reality/plumbing.py

  • Committer: Bazaar Package Importer
  • Author(s): Moshe Zadka
  • Date: 2002-03-08 07:14:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020308071416-oxvuw76tpcpi5v1q
Tags: upstream-0.15.5
ImportĀ upstreamĀ versionĀ 0.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
# Twisted, the Framework of Your Internet
 
3
# Copyright (C) 2001 Matthew W. Lefkowitz
 
4
 
5
# This library is free software; you can redistribute it and/or
 
6
# modify it under the terms of version 2.1 of the GNU Lesser General Public
 
7
# License as published by the Free Software Foundation.
 
8
 
9
# This library is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
# Lesser General Public License for more details.
 
13
 
14
# You should have received a copy of the GNU Lesser General Public
 
15
# License along with this library; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
"""Plumbing classes (pump, pipeline) to put Twisted Reality on the net.
 
19
"""
 
20
 
 
21
import md5
 
22
import string
 
23
from cStringIO import StringIO
 
24
 
 
25
from twisted.reality import player
 
26
from twisted.protocols import telnet, protocol, http
 
27
from twisted.python import log
 
28
from twisted.internet import tcp
 
29
from twisted.web import resource, html, widgets, guard
 
30
from twisted import copyright
 
31
 
 
32
# New-style Imports
 
33
from twisted.cred.util import Unauthorized
 
34
 
 
35
portno  = 8889
 
36
tportno = 8888
 
37
 
 
38
class Hose(telnet.Telnet):
 
39
    """A telnet protocol implementation for TR.
 
40
    """
 
41
    mode = "User"
 
42
 
 
43
    def welcomeMessage(self):
 
44
        """A message welcoming you to TR.
 
45
        """
 
46
        return "\r\nTwisted Reality %s\r\n" % copyright.version
 
47
 
 
48
 
 
49
    def loginPrompt(self):
 
50
        """A login prompt that asks for your character name.
 
51
        """
 
52
        return "character: "
 
53
 
 
54
 
 
55
    def processPassword(self, password):
 
56
        """Checks authentication against the reality; returns a boolean indicating success.
 
57
        """
 
58
        self.transport.write(telnet.IAC+ telnet.WONT+ telnet.ECHO+".....\r\n")
 
59
        req = self.factory.reality.application.authorizer.getIdentityRequest(self.username)
 
60
        self.pw = password
 
61
        req.addCallbacks(self.loggedIn, self.notLoggedIn)
 
62
        req.arm()
 
63
        # kludge; this really ought to be called later, but since the arm()
 
64
        # call actually calls self.loggedIn, then the return value of this
 
65
        # function will be used to assign to self.mode... ugh.
 
66
        if self.mode == 'Command':
 
67
            return 'Command'
 
68
        return "Pending"
 
69
 
 
70
    def loggedIn(self, identity):
 
71
        """The player's identity has been retrieved.  Now, check their password.
 
72
        """
 
73
        if identity.verifyPlainPassword(self.pw):
 
74
            # The identity checks out.
 
75
            characters = []
 
76
            # XXX REFACTOR: Hmm.  Is this next bit common behavior?
 
77
            r = self.factory.reality
 
78
            nm = r.getServiceName()
 
79
            for serviceName, perspectiveName in identity.getAllKeys():
 
80
                if serviceName == nm:
 
81
                    ### XXX FIXME
 
82
                    ### This can't really be done this way.
 
83
                    ### getPerspectiveNamed ought to be asynchronous.
 
84
                    characters.append(r.getPerspectiveNamed(perspectiveName))
 
85
            lc = len(characters)
 
86
            if lc == 1:
 
87
                p = characters[0]
 
88
            elif lc > 1:
 
89
                p = characters[0]
 
90
                self.transport.write("TODO: character selection menu\r\n")
 
91
            else:
 
92
                raise Unauthorized("that identity has no TR characters")
 
93
 
 
94
            p = p.attached(self, identity)
 
95
            self.player = p
 
96
            self.identity = identity
 
97
            self.transport.write("Hello "+self.player.name+", welcome to Reality!\r\n"+
 
98
                                 telnet.IAC+telnet.WONT+telnet.ECHO)
 
99
            self.mode = "Command"
 
100
        else:
 
101
            log.msg("incorrect password") 
 
102
            self.transport.loseConnection()
 
103
 
 
104
    def notLoggedIn(self, err):
 
105
        log.msg('requested bad username')
 
106
        self.transport.loseConnection()
 
107
 
 
108
    def processPending(self, pend):
 
109
        self.transport.write("Please hold...\r\n")
 
110
        return "Pending"
 
111
 
 
112
    def processCommand(self, cmd):
 
113
        """Execute a command as a player.
 
114
        """
 
115
        self.player.execute(cmd)
 
116
        return "Command"
 
117
 
 
118
    def connectionLost(self):
 
119
        """Disconnect player from this Intelligence, and clean up connection.
 
120
        """
 
121
        telnet.Telnet.connectionLost(self)
 
122
        if hasattr(self, 'player'):
 
123
            if hasattr(self.player, 'intelligence'):
 
124
                self.player.detached(self, self.identity)
 
125
 
 
126
    def seeName(self, name):
 
127
        """Display a focused name bracketed, in bold.
 
128
        """
 
129
        self.transport.write(telnet.BOLD_MODE_ON+"[ "+name+" ]"+telnet.BOLD_MODE_OFF+
 
130
                             "\r\n")
 
131
 
 
132
    def callRemote(self, key, *args, **kw):
 
133
        # pass-through of remote methods
 
134
        apply(getattr(self, key), args, kw)
 
135
 
 
136
 
 
137
    def seeItem(self, key, parent, value):
 
138
        """Display an item that's present.
 
139
        """
 
140
        self.transport.write(" "+value+"\r\n")
 
141
 
 
142
    def dontSeeItem(self, key, parent):
 
143
        """no-op; would be nonsensical over telnet.
 
144
        """
 
145
 
 
146
    def seeNoItems(self):
 
147
        """no-op; would be nonsensical over telnet.
 
148
        """
 
149
 
 
150
    def seeExit(self, direction):
 
151
        """Display a single exit.
 
152
        """
 
153
        self.transport.write("You can go "+direction+"\r\n")
 
154
 
 
155
    def dontSeeExit(self, direction):
 
156
        """no-op; would be nonsensical over telnet.
 
157
        """
 
158
 
 
159
    def seeNoExits(self):
 
160
        """no-op; would be nonsensical over telnet.
 
161
        """
 
162
 
 
163
    def seeDescription(self, key, description):
 
164
        """Displays a description.
 
165
        """
 
166
        self.transport.write(description+"\r\n")
 
167
 
 
168
    def dontSeeDescription(self, key):
 
169
        """no-op; would be nonsensical over telnet.
 
170
        """
 
171
 
 
172
    def seeNoDescriptions(self):
 
173
        """no-op; would be nonsensical over telnet.
 
174
        """
 
175
 
 
176
    def seeEvent(self, string):
 
177
        """Displays an event to the player.
 
178
        """
 
179
        self.transport.write(string+'\r\n')
 
180
 
 
181
    def request(self, question,default,ok,cancel):
 
182
        """Requests are not supported by this interface; calls cancel() immediately.
 
183
        """
 
184
        self.transport.write('edit operations not supported in telnet!\r\n')
 
185
        cancel()
 
186
 
 
187
 
 
188
 
 
189
class Spigot(protocol.Factory):
 
190
    """
 
191
    A telnet factory for twisted.reality.
 
192
    """
 
193
 
 
194
    def buildProtocol(self, addr):
 
195
        p = Hose()
 
196
        p.factory = self
 
197
        return p
 
198
    
 
199
    def __init__(self, world):
 
200
        """Initialize with a twisted.reality.Reality instance.
 
201
        """
 
202
        self.reality = world
 
203
 
 
204
class ThingWidget(widgets.StreamWidget):
 
205
    """A web-based interface to a twisted.reality.thing.Thing.
 
206
    """
 
207
    def __init__(self, thing):
 
208
        """Initialize with a particular thing.
 
209
        """
 
210
        self.thing = thing
 
211
 
 
212
    def getTitle(self, request):
 
213
        """Return a page title formatting the request.
 
214
        """
 
215
        session = request.getSession()
 
216
        return "Twisted Reality: %s" % self.thing.shortName(session.truser)
 
217
 
 
218
    def stream(self, write, request):
 
219
        """Display representation of a Thing (or move a Thing and redirect, depending on URI).
 
220
        """
 
221
        player = request.getSession().truser
 
222
        if request.args.has_key("action"):
 
223
            # cheating...
 
224
            # request.setHeader("refresh","0; URL=%s" % (request.prePathURL()))
 
225
            player.location = self.thing
 
226
            log.msg("Eep?")
 
227
            write("I have an action key! %s, %s" % (player.location, self.thing))
 
228
            # write("Redirecting...")
 
229
        write("<table><tr><td colspan=2>")
 
230
        write(self.thing.descriptionTo(player))
 
231
        write('<br><A HREF="%s?action=moveMe">Move Me Here</a>' %
 
232
              (request.prePathURL()))
 
233
        write("</td></tr><tr><td><ul>")
 
234
        for thing in self.thing.getThings(player):
 
235
            write('<LI><A HREF="%s">%s</A>' % (
 
236
                thing.thing_id,
 
237
                thing.presentPhrase(player)))
 
238
        if self.thing in player.locations:
 
239
            write('<hr><li><A HREF="%s">You are here.</a>' % (player.thing_id))
 
240
        write("</ul></td><td>")
 
241
        write("<UL>")
 
242
        for direc in self.thing.exits:
 
243
            dest = self.thing.findExit(direc)
 
244
            write("<LI>")
 
245
            write(direc)
 
246
            write(": ")
 
247
            write('<A HREF="%s">' % dest.thing_id)
 
248
            write(dest.shortName(player))
 
249
            write('</A>')
 
250
        write("</UL>")
 
251
        write("</td></tr></table>")
 
252
 
 
253
class Web(guard.ResourceGuard):
 
254
    def __init__(self, reality):
 
255
        guard.ResourceGuard.__init__(self, _Web(reality), reality, 'realIdent', 'truser')
 
256
 
 
257
class _Web(widgets.Gadget, widgets.StreamWidget):
 
258
    """A web interface to a twisted.reality.reality.Reality.
 
259
    """
 
260
    def __init__(self, in_reality):
 
261
        """Initialize with a reality.
 
262
        """
 
263
        widgets.Gadget.__init__(self)
 
264
        self.reality = in_reality
 
265
 
 
266
    def getWidget(self, name, request):
 
267
        """Get a Thing from this reality.
 
268
        """
 
269
        return ThingWidget(self.reality.getThingById(int(name)))
 
270
 
 
271
    def stream(self, write, request):
 
272
        """List all availble Things and there IDs
 
273
        """
 
274
        player = request.getSession().truser
 
275
        write('<UL>\n')
 
276
        for thing in self.reality.objects():
 
277
            np = thing.nounPhrase(player)
 
278
            write('<LI><A HREF="%s">%s</a>\n'% (str(thing.thing_id),np))
 
279
        write('</UL>\n')
 
280