SVN: r25690 - trunk/quixote/demo
David Binger <dbinger-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Mon, 6 Dec 2004 19:01:41 -0500
| Newsgroups | gmane.comp.web.quixote.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: dbinger
Date: 2004-11-30 15:17:30 -0500 (Tue, 30 Nov 2004)
New Revision: 25690
Removed:
trunk/quixote/demo/session.ptl
trunk/quixote/demo/session_demo.cgi
Log:
Remove old session demo. The altdemo.py serves this purpose.
Deleted: trunk/quixote/demo/session.ptl
===================================================================
--- trunk/quixote/demo/session.ptl 2004-11-30 20:06:25 UTC (rev 25689)
+++ trunk/quixote/demo/session.ptl 2004-11-30 20:17:30 UTC (rev 25690)
@@ -1,153 +0,0 @@
-"""$URL$
-$Id$
-
-Application code for the Quixote session management demo.
-Driver script is session_demo.cgi.
-"""
-
-from quixote import get_session_manager, get_session, get_request, get_field
-from quixote.directory import Directory
-from quixote.errors import QueryError
-
-# Typical stuff for any Quixote app.
-
-def page_header [html] (title):
- '''\
- <html>
- <head><title>%s</title></head>
- <body>
- <h1>%s</h1>
- ''' % (title, title)
-
-def page_footer [html] ():
- '''\
- </body>
- </html>
- '''
-
-
-# We include the login form on two separate pages, so it's been factored
-# out to a separate template.
-
-def login_form [html] ():
- '''\
- <form method="POST" action="login">
- <input name="name" width=30>
- <input type="submit">
- </form>
- '''
-
-
-class SessionUI(Directory):
-
- _q_exports = ['', 'login', 'logout']
-
- def _q_index [html] (self):
- page_header("Quixote Session Management Demo")
-
- session = get_session()
-
- # All Quixote sessions have the ability to track the user's identity
- # in session.user. In this simple application, session.user is just
- # a string which the user enters directly into this form. In the
- # real world, you would of course use a more sophisticated form of
- # authentication (eg. enter a password over an SSL connection), and
- # session.user might be an object with information about the user
- # (their email address, password hash, preferences, etc.).
-
- if session.user is None:
- '''
- <p>You haven\'t introduced yourself yet.<br>
- Please tell me your name:
- '''
- login_form()
- else:
- '<p>Hello, %s. Good to see you again.</p>\n' % session.user
-
- '''
- You can now:
- <ul>
- '''
- if session.user:
- ' <li><a href="login">become someone else</a> (login again)\n'
- ' <li><a href="logout">leave this session</a> (logout)\n'
- '</ul>\n'
-
- # The other piece of information we track here is the number of
- # requests made in each session; report that information for the
- # current session here.
- """\
- <p>Your session is <code>%s</code><br>
- You have made %d request(s) (including this one) in this session.</p>
- """ % (repr(session), session.num_requests)
-
- # The session manager is the collection of all sessions managed by
- # the current publisher, ie. in this process. Poking around in the
- # session manager is not something you do often, but it's really
- # handy for debugging/site administration.
- mgr = get_session_manager()
- session_ids = mgr.keys()
- '''
- <p>The current session manager is <code>%s</code><br>
- It has %d session(s) in it right now:</p>
- <table border=1>
- <tr><th>session id</th><th>user</th><th>num requests</th></tr>
- ''' % (repr(mgr), len(session_ids))
- for sess_id in session_ids:
- sess = mgr[sess_id]
- (' <tr><td>%s</td><td>%s</td><td>%d</td>\n'
- % (sess.id,
- sess.user and sess.user or "<i>none</i>",
- sess.num_requests))
- '<table>\n'
-
- page_footer()
-
-
- # The login() template has two purposes: to display a page with just a
- # login form, and to process the login form submitted either from the
- # index page or from login() itself. This is a fairly common idiom in
- # Quixote (just as it's a fairly common idiom with CGI scripts -- it's
- # just cleaner with Quixote).
-
- def login [html] (self):
- page_header("Quixote Session Demo: Login")
- session = get_session()
-
- # We seem to be processing the login form.
- if get_request().form:
- user = get_field("name")
- if not user:
- raise QueryError("no user name supplied")
-
- session.user = user
-
- '<p>Welcome, %s! Thank you for logging in.</p>\n' % user
- '<a href="./">back to start</a>\n'
-
- # No form data to process, so generate the login form instead. When
- # the user submits it, we'll return to this template and take the
- # above branch.
- else:
- '<p>Please enter your name here:</p>\n'
- login_form()
-
- page_footer()
-
-
- # logout() just expires the current session, ie. removes it from the
- # session manager and instructs the client to forget about the session
- # cookie. The only code necessary is the call to
- # SessionManager.expire_session() -- the rest is just user interface.
-
- def logout [html] (self):
- page_header("Quixote Session Demo: Logout")
- session = get_session()
- if session.user:
- '<p>Goodbye, %s. See you around.</p>\n' % session.user
-
- get_session_manager().expire_session()
-
- '<p>Your session has been expired.</p>\n'
- '<p><a href="./">start over</a></p>\n'
- page_footer()
Deleted: trunk/quixote/demo/session_demo.cgi
===================================================================
--- trunk/quixote/demo/session_demo.cgi 2004-11-30 20:06:25 UTC (rev 25689)
+++ trunk/quixote/demo/session_demo.cgi 2004-11-30 20:17:30 UTC (rev 25690)
@@ -1,171 +0,0 @@
-#!/www/python/bin/python
-
-# Demonstrate Quixote session management, along with the application
-# code in session.ptl (aka quixote.demo.session).
-
-__revision__ = "$Id$"
-
-import os
-from stat import ST_MTIME
-from time import time
-from cPickle import load, dump
-from quixote import enable_ptl
-from quixote.session import Session, SessionManager
-from quixote.publish import SessionPublisher
-
-class DemoSession (Session):
- """
- Session class that tracks the number of requests made within a
- session.
- """
-
- def __init__ (self, request, id):
- Session.__init__(self, request, id)
- self.num_requests = 0
-
- def start_request (self, request):
-
- # This is called from the main object publishing loop whenever
- # we start processing a new request. Obviously, this is a good
- # place to track the number of requests made. (If we were
- # interested in the number of *successful* requests made, then
- # we could override finish_request(), which is called by
- # the publisher at the end of each successful request.)
-
- Session.start_request(self, request)
- self.num_requests += 1
-
- def has_info (self):
-
- # Overriding has_info() is essential but non-obvious. The
- # session manager uses has_info() to know if it should hang on
- # to a session object or not: if a session is "dirty", then it
- # must be saved. This prevents saving sessions that don't need
- # to be saved, which is especially important as a defensive
- # measure against clients that don't handle cookies: without it,
- # we might create and store a new session object for every
- # request made by such clients. With has_info(), we create the
- # new session object every time, but throw it away unsaved as
- # soon as the request is complete.
- #
- # (Of course, if you write your session class such that
- # has_info() always returns true after a request has been
- # processed, you're back to the original problem -- and in fact,
- # this class *has* been written that way, because num_requests
- # is incremented on every request, which makes has_info() return
- # true, which makes SessionManager always store the session
- # object. In a real application, think carefully before putting
- # data in a session object that causes has_info() to return
- # true.)
-
- return (self.num_requests > 0) or Session.has_info(self)
-
- is_dirty = has_info
-
-
-class DirMapping:
- """A mapping object that stores values as individual pickle
- files all in one directory. You wouldn't want to use this in
- production unless you're using a filesystem optimized for
- handling large numbers of small files, like ReiserFS. However,
- it's pretty easy to implement and understand, it doesn't require
- any external libraries, and it's really easy to browse the
- "database".
- """
-
- def __init__ (self, save_dir=None):
- self.set_save_dir(save_dir)
- self.cache = {}
- self.cache_time = {}
-
- def set_save_dir (self, save_dir):
- self.save_dir = save_dir
- if save_dir and not os.path.isdir(save_dir):
- os.mkdir(save_dir, 0700)
-
- def keys (self):
- return os.listdir(self.save_dir)
-
- def values (self):
- # This is pretty expensive!
- return [self[id] for id in self.keys()]
-
- def items (self):
- return [(id, self[id]) for id in self.keys()]
-
- def _gen_filename (self, session_id):
- return os.path.join(self.save_dir, session_id)
-
- def __getitem__ (self, session_id):
-
- filename = self._gen_filename(session_id)
- if (self.cache.has_key(session_id) and
- os.stat(filename)[ST_MTIME] <= self.cache_time[session_id]):
- return self.cache[session_id]
-
- if os.path.exists(filename):
- try:
- file = open(filename, "rb")
- try:
- print "loading session from %r" % file
- session = load(file)
- self.cache[session_id] = session
- self.cache_time[session_id] = time()
- return session
- finally:
- file.close()
- except IOError, err:
- raise KeyError(session_id,
- "error reading session from %s: %s"
- % (filename, err))
- else:
- raise KeyError(session_id,
- "no such file %s" % filename)
-
- def get (self, session_id, default=None):
- try:
- return self[session_id]
- except KeyError:
- return default
-
- def has_key (self, session_id):
- return os.path.exists(self._gen_filename(session_id))
-
- def __setitem__ (self, session_id, session):
- filename = self._gen_filename(session.id)
- file = open(filename, "wb")
- print "saving session to %s" % file
- dump(session, file, 1)
- file.close()
-
- self.cache[session_id] = session
- self.cache_time[session_id] = time()
-
- def __delitem__ (self, session_id):
- filename = self._gen_filename(session_id)
- if os.path.exists(filename):
- os.remove(filename)
- if self.cache.has_key(session_id):
- del self.cache[session_id]
- del self.cache_time[session_id]
- else:
- raise KeyError(session_id, "no such file: %s" % filename)
-
-
-# This is mostly the same as the standard boilerplate for any Quixote
-# driver script. The main difference is that we have to instantiate a
-# session manager, and use SessionPublisher instead of the normal
-# Publisher class.
-
-# You can use the 'shelve' module to create an alternative persistent
-# mapping to the DirMapping class above.
-#import shelve
-#sessions = shelve.open("/tmp/quixote-sessions")
-
-enable_ptl()
-sessions = DirMapping(save_dir="/tmp/quixote-session-demo")
-session_mgr = SessionManager(session_class=DemoSession,
- session_mapping=sessions)
-app = SessionPublisher('quixote.demo.session', session_mgr=session_mgr,
- display_exceptions='plain')
-app.publish_cgi()