SVN: r25365 - in trunk/quixote: . demo form

Neil Schemenauer <nascheme-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Fri, 15 Oct 2004 12:32:16 -0400
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Author: nascheme
Date: 2004-10-15 12:30:07 -0400 (Fri, 15 Oct 2004)
New Revision: 25365

Modified:
   trunk/quixote/__init__.py
   trunk/quixote/demo/__init__.py
   trunk/quixote/demo/forms.ptl
   trunk/quixote/demo/integer_ui.py
   trunk/quixote/demo/pages.ptl
   trunk/quixote/demo/session.ptl
   trunk/quixote/errors.py
   trunk/quixote/form/compatibility.py
   trunk/quixote/publish.py
   trunk/quixote/session.py
   trunk/quixote/util.py
Log:
Stop passing 'request' around.


Modified: trunk/quixote/__init__.py
===================================================================
--- trunk/quixote/__init__.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/__init__.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -17,8 +17,8 @@
 # These are frequently needed by Quixote applications, so make them easy
 # to get at.
 from quixote.publish import Publisher, \
-     get_publisher, get_request, get_path, redirect, \
-     get_session, get_session_manager, get_user
+     get_publisher, get_request, get_response, get_path, redirect, \
+     get_session, get_session_manager, get_user, get_field, get_cookie
 
 # Can't think of anywhere better to put this, so here it is.
 def enable_ptl():

Modified: trunk/quixote/demo/__init__.py
===================================================================
--- trunk/quixote/demo/__init__.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/demo/__init__.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -4,24 +4,25 @@
               ("favicon.ico", "q_ico")]
 
 import sys
+from quixote import get_response
 from quixote.demo.pages import _q_index, _q_exception_handler, dumpreq
 from quixote.demo.integer_ui import IntegerUI
 from quixote.errors import PublishError
 from quixote.util import StaticDirectory, StaticFile
 
-def simple(request):
+def simple():
     # This function returns a plain text document, not HTML.
-    request.response.set_content_type("text/plain")
+    get_response().set_content_type("text/plain")
     return "This is the Python function 'quixote.demo.simple'.\n"
 
-def error(request):
+def error():
     raise ValueError, "this is a Python exception"
 
-def publish_error(request):
+def publish_error():
     raise PublishError(public_msg="Publishing error raised by publish_error")
 
-def _q_lookup(request, component):
-    return IntegerUI(request, component)
+def _q_lookup(component):
+    return IntegerUI(component)
 
 def _q_resolve(component):
     # _q_resolve() is a hook that can be used to import only

Modified: trunk/quixote/demo/forms.ptl
===================================================================
--- trunk/quixote/demo/forms.ptl	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/demo/forms.ptl	2004-10-15 16:30:07 UTC (rev 25365)
@@ -32,7 +32,7 @@
             Topping('anchovies', 30),
             Topping('onions', 25)]
 
-def form_demo(request):
+def form_demo():
     # build form
     form = Form()
     form.add(StringWidget, "name", title="Your Name",

Modified: trunk/quixote/demo/integer_ui.py
===================================================================
--- trunk/quixote/demo/integer_ui.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/demo/integer_ui.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -1,4 +1,5 @@
 import sys
+from quixote import get_response, redirect
 from quixote.errors import TraversalError
 
 def fact(n):
@@ -12,20 +13,20 @@
 
     _q_exports = ["factorial", "prev", "next"]
 
-    def __init__(self, request, component):
+    def __init__(self, component):
         try:
             self.n = int(component)
         except ValueError, exc:
             raise TraversalError(str(exc))
 
-    def factorial(self, request):
+    def factorial(self):
         if self.n > 10000:
             sys.stderr.write("warning: possible denial-of-service attack "
                              "(request for factorial(%d))\n" % self.n)
-        request.response.set_header("content-type", "text/plain")
+        get_response().set_header("content-type", "text/plain")
         return "%d! = %d\n" % (self.n, fact(self.n))
 
-    def _q_index(self, request):
+    def _q_index(self):
         return """\
 <html>
 <head><title>The Number %d</title></head>
@@ -52,8 +53,8 @@
 </html>
 """ % (self.n, self.n, self.n, self.n-1, self.n+1)
 
-    def prev(self, request):
-        return request.redirect("../%d/" % (self.n-1))
+    def prev(self):
+        return redirect("../%d/" % (self.n-1))
 
-    def next(self, request):
-        return request.redirect("../%d/" % (self.n+1))
+    def next(self):
+        return redirect("../%d/" % (self.n+1))

Modified: trunk/quixote/demo/pages.ptl
===================================================================
--- trunk/quixote/demo/pages.ptl	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/demo/pages.ptl	2004-10-15 16:30:07 UTC (rev 25365)
@@ -7,7 +7,7 @@
 
 from quixote.util import dump_request
 
-def _q_index [html] (request):
+def _q_index [html] ():
     print "debug message from the index page"
     package_name = str('.').join(__name__.split(str('.'))[:-1])
     module_name = __name__
@@ -56,7 +56,7 @@
     </html>
     """ % vars()
 
-def _q_exception_handler [html] (request, exc):
+def _q_exception_handler [html] (exc):
     """
     <html>
     <head><title>Quixote Demo</title></head>
@@ -72,14 +72,14 @@
     </html>
     """ % (exc, exc)
 
-def dumpreq [html] (request):
+def dumpreq [html] ():
     """
     <html>
     <head><title>HTTPRequest Object</title></head>
     <body>
     <h1>HTTPRequest Object</h1>
     """
-    dump_request(request)
+    dump_request()
     """
     </body>
     </html>

Modified: trunk/quixote/demo/session.ptl
===================================================================
--- trunk/quixote/demo/session.ptl	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/demo/session.ptl	2004-10-15 16:30:07 UTC (rev 25365)
@@ -5,7 +5,7 @@
 
 __revision__ = "$Id$"
 
-from quixote import get_session_manager
+from quixote import get_session_manager, get_session, get_request, get_field
 from quixote.errors import QueryError
 
 _q_exports = ['login', 'logout']
@@ -40,10 +40,10 @@
 '''
 
 
-def _q_index [html] (request):
+def _q_index [html] ():
     page_header("Quixote Session Management Demo")
 
-    session = request.session
+    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
@@ -108,13 +108,14 @@
 # Quixote (just as it's a fairly common idiom with CGI scripts -- it's
 # just cleaner with Quixote).
 
-def login [html] (request):
+def login [html] ():
     page_header("Quixote Session Demo: Login")
-    session = request.session
+    request = get_request()
+    session = get_session()
 
     # We seem to be processing the login form.
     if request.form:
-        user = request.form.get("name")
+        user = get_field("name")
         if not user:
             raise QueryError("no user name supplied")
 
@@ -138,13 +139,13 @@
 # cookie.  The only code necessary is the call to
 # SessionManager.expire_session() -- the rest is just user interface.
 
-def logout [html] (request):
+def logout [html] ():
     page_header("Quixote Session Demo: Logout")
-    session = request.session
+    session = get_session()
     if session.user:
         '<p>Goodbye, %s.  See you around.</p>\n' % session.user
 
-    get_session_manager().expire_session(request)
+    get_session_manager().expire_session()
 
     '<p>Your session has been expired.</p>\n'
     '<p><a href="./">start over</a></p>\n'

Modified: trunk/quixote/errors.py
===================================================================
--- trunk/quixote/errors.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/errors.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -43,7 +43,7 @@
     def __str__(self):
         return self.private_msg or self.public_msg or "???"
 
-    def format(self, request):
+    def format(self):
         msg = htmlescape(self.title)
         if self.public_msg:
             msg = msg + ": " + self.public_msg
@@ -76,7 +76,7 @@
             path = quixote.get_request().get_path()
         self.path = path
 
-    def format(self, request):
+    def format(self):
         msg = htmlescape(self.title) + ": " + self.path
         if self.public_msg:
             msg = msg + ": " + self.public_msg
@@ -137,17 +137,17 @@
         PublishError.__init__(self, public_msg, private_msg)
         self.session_id = session_id
 
-    def format(self, request):
+    def format(self):
         from quixote import get_session_manager
-        get_session_manager().revoke_session_cookie(request)
-        msg = PublishError.format(self, request)
+        get_session_manager().revoke_session_cookie()
+        msg = PublishError.format(self)
         if self.session_id:
             msg = msg + ": " + self.session_id
         return msg
 
 
-def default_exception_handler(request, exc):
-    """(request : HTTPRequest, exc : PublishError) -> string
+def default_exception_handler(exc):
+    """(exc : PublishError) -> string
 
     Format a PublishError exception as a web page.  This is the default
     handler called if no '_q_exception_handler' function was found while
@@ -163,4 +163,4 @@
       <p>%s</p>
       </body>
     </html>
-    """) % (exc.title, exc.description, exc.format(request))
+    """) % (exc.title, exc.description, exc.format())

Modified: trunk/quixote/form/compatibility.py
===================================================================
--- trunk/quixote/form/compatibility.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/form/compatibility.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -5,6 +5,7 @@
 class (useful for transitioning existing forms).
 '''
 
+from quixote import get_request, get_path, redirect
 from quixote.form import Form as _Form, Widget, StringWidget, FileWidget, \
     PasswordWidget, TextWidget, CheckboxWidget, RadiobuttonsWidget, \
     SingleSelectWidget, SelectWidget, OptionSelectWidget, \
@@ -50,48 +51,50 @@
         self.add_submit("cancel", caption)
         self.cancel_url = url
 
-    def get_action_url(self, request):
-        action_url = url_quote(request.get_path())
-        query = request.get_environ("QUERY_STRING")
+    def get_action_url(self):
+        action_url = url_quote(get_path())
+        query = get_request().get_environ("QUERY_STRING")
         if query:
             action_url += "?" + query
         return action_url
 
-    def render(self, request, action_url=None):
+    def render(self, action_url=None):
         if action_url:
             self.action_url = action_url
         return _Form.render(self)
 
-    def process(self, request):
+    def process(self):
         values = {}
+        request = get_request()
         for name, widget in self._names.items():
-            values[name] = widget.parse(request)
+            values[name] = widget.parse()
         return values
 
-    def action(self, request, submit, values):
+    def action(self, submit, values):
         raise NotImplementedError, "sub-classes must implement 'action()'"
 
-    def handle(self, request):
-        """handle(request : HTTPRequest) -> string
+    def handle(self):
+        """handle() -> string
 
         Master method for handling forms.  It should be called after
         initializing a form.  Controls form action based on a request.  You
         probably should override 'process' and 'action' instead of
         overriding this method.
         """
+        request = get_request()
         if not self.is_submitted():
-            return self.render(request, self.action_url)
+            return self.render(self.action_url)
         submit = self.get_submit()
         if submit == "cancel":
-            return request.redirect(self.cancel_url)
-        values = self.process(request)
+            return redirect(self.cancel_url)
+        values = self.process()
         if submit == True:
             # The form was submitted by an unregistered submit button, assume
             # that the submission was required to update the layout of the form.
             self.clear_errors()
-            return self.render(request, self.action_url)
+            return self.render(self.action_url)
 
         if self.has_errors():
-            return self.render(request, self.action_url)
+            return self.render(self.action_url)
         else:
-            return self.action(request, submit, values)
+            return self.action(submit, values)

Modified: trunk/quixote/publish.py
===================================================================
--- trunk/quixote/publish.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/publish.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -17,7 +17,7 @@
 
 from quixote import errors
 from quixote.html import htmltext
-from quixote.util import dump_request
+from quixote import util
 from quixote.http_request import HTTPRequest
 from quixote.http_response import HTTPResponse, Stream
 from quixote.sendmail import sendmail
@@ -199,7 +199,7 @@
         """
         request.process_inputs()
 
-    def start_request(self, request):
+    def start_request(self):
         """Called at the start of each request.  Overridden by
         SessionPublisher to handle session details.
         """
@@ -259,12 +259,12 @@
                                    ))
 
 
-    def finish_successful_request(self, request):
+    def finish_successful_request(self):
         """Called at the end of a successful request.  Overridden by
         SessionPublisher to handle session details."""
         pass
 
-    def finish_interrupted_request(self, request, exc):
+    def finish_interrupted_request(self, exc):
         """
         Called at the end of an interrupted request.  Requests are
         interrupted by raising a PublishError exception.  This method
@@ -283,6 +283,7 @@
 
         # Throw away the existing response object and start a new one
         # for the error document we're going to create here.
+        request = get_request()
         request.response = HTTPResponse()
 
         # set response status code so every custom doesn't have to do it
@@ -304,13 +305,13 @@
                 handler = errors.default_exception_handler
 
             try:
-                return handler(request, exc)
+                return handler(exc)
             except errors.PublishError:
                 assert handler is not errors.default_exception_handler
                 continue # exception was re-raised or another exception occured
 
 
-    def finish_failed_request(self, request):
+    def finish_failed_request(self):
         """
         Called at the end of an failed request.  Any exception (other
         than PublishError) causes a request to fail.  This method should
@@ -318,6 +319,7 @@
         request.
         """
         # build new response to be safe
+        request = get_request()
         original_response = request.response
         request.response = HTTPResponse()
         #self.log("caught an error (%s), reporting it." %
@@ -386,7 +388,7 @@
         hook = cgitb.Hook(file=error_file)
         hook(exc_type, exc_value, tb)
         error_file.write('<h2>Original Request</h2>')
-        error_file.write(dump_request(request))
+        error_file.write(util.dump_request(request))
         error_file.write('<h2>Original Response</h2><pre>')
         original_response.write(error_file)
         error_file.write('</pre>')
@@ -412,7 +414,7 @@
         the output is returned.  Exceptions are handled by the caller.
         """
 
-        self.start_request(request)
+        self.start_request()
 
         # Initialize the publisher's namespace_stack
         self.namespace_stack = []
@@ -433,7 +435,7 @@
         # ...or a callable.
         elif callable(object):
             try:
-                output = object(request)
+                output = object()
             except SystemExit:
                 output = "SystemExit exception caught, shutting down"
                 self.log(output)
@@ -449,7 +451,7 @@
 
 
         # The callable ran OK, commit any changes to the session
-        self.finish_successful_request(request)
+        self.finish_successful_request()
 
         return output
 
@@ -507,7 +509,7 @@
             output = self.finish_interrupted_request(request, exc)
         except:
             # Some other exception, generate error messages to the logs, etc.
-            output = self.finish_failed_request(request)
+            output = self.finish_failed_request()
         output = self.filter_output(request, output)
         self.log_request(request, start_time)
         return output
@@ -577,19 +579,21 @@
     def set_session_manager(self, session_mgr):
         self.session_mgr = session_mgr
 
-    def start_request(self, request):
+    def start_request(self):
         # Get the session object and stick it onto the request
-        request.session = self.session_mgr.get_session(request)
-        request.session.start_request(request)
+        request = get_request()
+        request.session = self.session_mgr.get_session()
+        request.session.start_request()
 
-    def finish_successful_request(self, request):
-        if request.session is not None:
-            request.session.finish_request(request)
-            self.session_mgr.maintain_session(request, request.session)
-        self.session_mgr.commit_changes(request.session)
+    def finish_successful_request(self):
+        session = get_session()
+        if session is not None:
+            session.finish_request()
+            self.session_mgr.maintain_session(session)
+        self.session_mgr.commit_changes(session)
 
-    def finish_interrupted_request(self, request, exc):
-        output = Publisher.finish_interrupted_request(self, request, exc)
+    def finish_interrupted_request(self, exc):
+        output = Publisher.finish_interrupted_request(self, exc)
 
         # commit the current transaction so that any changes to the
         # session objects are saved and are visible on the next HTTP
@@ -607,14 +611,14 @@
         # XXX We should really be able to commit session changes and
         # database changes separately, but that requires ZODB
         # incantations that we currently don't know.
-        self.session_mgr.commit_changes(request.session)
+        self.session_mgr.commit_changes(get_session())
 
         return output
 
-    def finish_failed_request(self, request):
+    def finish_failed_request(self):
         if self.session_mgr:
-            self.session_mgr.abort_changes(request.session)
-        return Publisher.finish_failed_request(self, request)
+            self.session_mgr.abort_changes(get_session())
+        return Publisher.finish_failed_request(self)
 
 # class SessionPublisher
 
@@ -747,7 +751,7 @@
     # Second security check: call _q_access function if it's present.
     if hasattr(container, '_q_access'):
         # will raise AccessError if access failed
-        container._q_access(request)
+        container._q_access()
 
     # Third security check: make sure the current name component
     # is in the export list or is '_q_index'.  If neither
@@ -781,11 +785,11 @@
         # Component is not in exports list.
         object = None
         if hasattr(container, "_q_lookup"):
-            object = container._q_lookup(request, component)
+            object = container._q_lookup(component)
         elif hasattr(container, "_q_getname"):
             warnings.warn("_q_getname() on %s used; should "
                           "be replaced by _q_lookup()" % type(container))
-            object = container._q_getname(request, component)
+            object = container._q_getname(component)
         if object is None:
             raise errors.TraversalError(
                 private_msg="object %r has no attribute %r" % (
@@ -799,7 +803,7 @@
 
     elif internal_name == '_q_index':
         if hasattr(container, "_q_lookup"):
-            object = container._q_lookup(request, "")
+            object = container._q_lookup("")
         else:
             raise errors.AccessError(
                 private_msg=("_q_index not found in %r" % container))
@@ -839,31 +843,33 @@
 _publisher = None
 
 def get_publisher():
-    global _publisher
     return _publisher
 
 def get_request():
-    global _publisher
     return _publisher.get_request()
 
+def get_response():
+    return _publisher.get_request().response
+
+def get_field(name, default=None):
+    return _publisher.get_request().get_field(name, default)
+
+def get_cookie(name, default=None):
+    return _publisher.get_request().get_cookie(name, default)
+
 def get_path(n=0):
-    global _publisher
     return _publisher.get_request().get_path(n)
 
 def redirect(location, permanent=False):
-    global _publisher
     return _publisher.get_request().redirect(location, permanent)
 
 def get_session():
-    global _publisher
     return _publisher.get_request().session
 
 def get_session_manager():
-    global _publisher
     return _publisher.session_mgr
 
 def get_user():
-    global _publisher
     session = _publisher.get_request().session
     if session is None:
         return None

Modified: trunk/quixote/session.py
===================================================================
--- trunk/quixote/session.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/session.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -23,7 +23,7 @@
 
 from time import time, localtime, strftime
 
-from quixote import get_publisher
+from quixote import get_publisher, get_cookie, get_response, get_request
 from quixote.errors import SessionError
 from quixote.util import randbytes
 
@@ -197,23 +197,23 @@
     # above mapping methods, and are concerned with all the high-
     # level details of managing web sessions
 
-    def new_session(self, request, id):
-        """new_session(request : HTTPRequest, id : string)
+    def new_session(self, id):
+        """new_session(id : string)
            -> Session
 
         Return a new session object, ie. an instance of the session_class
         class passed to the constructor (defaults to Session).
         """
-        return self.session_class(request, id)
+        return self.session_class(id)
 
-    def _get_session_id(self, request, config):
-        """_get_session_id(request : HTTPRequest) -> string
+    def _get_session_id(self, config):
+        """_get_session_id() -> string
 
         Find the ID of the current session by looking for the session
-        cookie in 'request'.  Return None if no such cookie or the
+        cookie in the reques'.  Return None if no such cookie or the
         cookie has been expired, otherwise return the cookie's value.
         """
-        id = request.cookies.get(config.session_cookie_name)
+        id = get_cookie(config.session_cookie_name)
         if id == "" or id == "*del*":
             return None
         else:
@@ -228,23 +228,23 @@
             id = randbytes(8)  # 64-bit random number
         return id
 
-    def _create_session(self, request):
+    def _create_session(self):
         # Create a new session object, with no ID for now - one will
         # be assigned later if we save the session.
-        return self.new_session(request, None)
+        return self.new_session(None)
 
-    def get_session(self, request):
-        """get_session(request : HTTPRequest) -> Session
+    def get_session(self):
+        """get_session() -> Session
 
         Fetch or create a session object for the current session, and
         return it.  If a session cookie is found in the HTTP request
-        object 'request', use it to look up and return an existing
-        session object.  If no session cookie is found, create a new
-        session.  If the session cookie refers to a non-existent
-        session, raise SessionError.  If the check_session_addr config
-        variable is true, then a mismatch between the IP address stored
-        in an existing session the IP address of the current request
-        also causes SessionError.
+        object, use it to look up and return an existing session object.
+        If no session cookie is found, create a new session.  If the
+        session cookie refers to a non-existent session, raise
+        SessionError.  If the check_session_addr config variable is
+        true, then a mismatch between the IP address stored in an
+        existing session the IP address of the current request also
+        causes SessionError.
 
         Note that this method does *not* cause the new session to be
         stored in the session manager, nor does it drop a session cookie
@@ -252,7 +252,7 @@
         maintain_session(), called at the end of a request.
         """
         config = get_publisher().config
-        id = self._get_session_id(request, config)
+        id = self._get_session_id(config)
         if id is not None:
             session = self.get(id)
             if session is None:
@@ -266,22 +266,22 @@
                 raise SessionError(session_id=id)
             if (config.check_session_addr and
                 session.get_remote_address() !=
-                request.get_environ("REMOTE_ADDR")):
+                get_request().get_environ("REMOTE_ADDR")):
                 raise SessionError("Remote IP address does not match the "
                                    "IP address that created the session",
                                    session_id=id)
 
         if id is None or session is None:
             # Generate a session ID and create the session.
-            session = self._create_session(request)
+            session = self._create_session()
 
         session._set_access_time(self.ACCESS_TIME_RESOLUTION)
         return session
 
     # get_session ()
 
-    def maintain_session(self, request, session):
-        """maintain_session(request : HTTPRequest, session : Session)
+    def maintain_session(self, session):
+        """maintain_session(session : Session)
 
         Maintain session information.  This method is called by
         SessionPublisher after servicing an HTTP request, just before
@@ -296,7 +296,7 @@
             # explicitly forget it.
             if session.id and self.has_session(session.id):
                 del self[session.id]
-                self.revoke_session_cookie(request)
+                self.revoke_session_cookie()
             return
 
         if session.id is None:
@@ -304,7 +304,7 @@
             # info -- store it and set the session cookie.
             session.id = self._make_session_id()
             self[session.id] = session
-            self.set_session_cookie(request, session.id)
+            self.set_session_cookie(session.id)
 
         elif session.is_dirty():
             # We have already stored this session, but it's dirty
@@ -314,48 +314,49 @@
             # repeatedly storing the same object in the same mapping.
             self[session.id] = session
 
-    def _set_cookie(self, request, value, **attrs):
+    def _set_cookie(self, value, **attrs):
         config = get_publisher().config
         name = config.session_cookie_name
         if config.session_cookie_path:
             path = config.session_cookie_path
         else:
-            path = request.environ['SCRIPT_NAME']
+            path = get_request().get_environ('SCRIPT_NAME')
             if not path.endswith("/"):
                 path += "/"
         domain = config.session_cookie_domain
-        request.response.set_cookie(name, value, domain=domain,
-                                    path=path, **attrs)
+        get_response().set_cookie(name, value, domain=domain,
+                                  path=path, **attrs)
         return name
 
-    def set_session_cookie(self, request, session_id):
-        """set_session_cookie(request : HTTPRequest, session_id : string)
+    def set_session_cookie(self, session_id):
+        """set_session_cookie(session_id : string)
 
         Ensure that a session cookie with value 'session_id' will be
-        returned to the client via 'request.response'.
+        returned to the client via the response object.
         """
-        self._set_cookie(request, session_id)
+        self._set_cookie(session_id)
 
-    def revoke_session_cookie(self, request):
-        """revoke_session_cookie(request : HTTPRequest)
+    def revoke_session_cookie(self):
+        """revoke_session_cookie()
 
         Remove the session cookie from the remote user's session by
-        resetting the value and maximum age in 'request.response'.  Also
-        remove the cookie from 'request' so that further processing of
+        resetting the value and maximum age in the response object.  Also
+        remove the cookie from the request so that further processing of
         this request does not see the cookie's revoked value.
         """
-        cookie_name = self._set_cookie(request, "", max_age=0)
-        if request.cookies.has_key(cookie_name):
-            del request.cookies[cookie_name]
+        cookie_name = self._set_cookie("", max_age=0)
+        if get_cookie(cookie_name) is not None:
+            del get_request().cookies[cookie_name]
 
-    def expire_session(self, request):
-        """expire_session(request : HTTPRequest)
+    def expire_session(self):
+        """expire_session()
 
         Expire the current session, ie. revoke the session cookie from
         the client and remove the session object from the session
-        manager and from 'request'.
+        manager and from the current request.
         """
-        self.revoke_session_cookie(request)
+        self.revoke_session_cookie()
+        request = get_request()
         try:
             del self[request.session.id]
         except KeyError:
@@ -365,19 +366,17 @@
             pass
         request.session = None
 
-    def has_session_cookie(self, request, must_exist=False):
-        """has_session_cookie(request : HTTPRequest,
-                              must_exist : boolean = false)
-           -> boolean
+    def has_session_cookie(self, must_exist=False):
+        """has_session_cookie(must_exist : boolean = false) -> bool
 
-        Return true if 'request' already has a cookie identifying a
+        Return true if the request already has a cookie identifying a
         session object.  If 'must_exist' is true, the cookie must
         correspond to a currently existing session; otherwise (the
         default), we just check for the existence of the session cookie
         and don't inspect its content at all.
         """
         config = get_publisher().config
-        id = request.cookies.get(config.session_cookie_name)
+        id = get_cookie(config.session_cookie_name)
         if id is None:
             return False
         if must_exist:
@@ -423,10 +422,10 @@
 
     MAX_FORM_TOKENS = 16 # maximum number of outstanding form tokens
 
-    def __init__(self, request, id):
+    def __init__(self, id):
         self.id = id
         self.user = None
-        self._remote_address = request.get_environ("REMOTE_ADDR")
+        self._remote_address = get_request().get_environ("REMOTE_ADDR")
         self._creation_time = self._access_time = time()
         self._form_tokens = [] # queue
 
@@ -479,8 +478,8 @@
 
     # -- Hooks into the Quixote main loop ------------------------------
 
-    def start_request(self, request):
-        """start_request(request : HTTPRequest)
+    def start_request(self):
+        """start_request()
 
         Called near the beginning of each request: after the HTTPRequest
         object has been built and this Session object has been fetched
@@ -488,10 +487,10 @@
         object found by URL traversal.
         """
         if self.user:
-            request.environ['REMOTE_USER'] = str(self.user)
+            get_request().environ['REMOTE_USER'] = str(self.user)
 
-    def finish_request(self, request):
-        """finish_request(request : HTTPRequest)
+    def finish_request(self):
+        """finish_request()
 
         Called near the end of each request: after a callable object has
         been found and (successfully) called.  Not called if there were

Modified: trunk/quixote/util.py
===================================================================
--- trunk/quixote/util.py	2004-10-15 15:47:55 UTC (rev 25364)
+++ trunk/quixote/util.py	2004-10-15 16:30:07 UTC (rev 25365)
@@ -24,6 +24,7 @@
 import xmlrpclib
 from cStringIO import StringIO
 from rfc822 import formatdate
+import quixote
 from quixote import errors
 from quixote.html import htmltext, TemplateIO
 from quixote.http_response import Stream
@@ -159,9 +160,10 @@
         self.encoding = encoding or guess_enc or None
         self.cache_time = cache_time
 
-    def __call__(self, request):
+    def __call__(self):
         stat = os.stat(self.path)
         last_modified = formatdate(stat.st_mtime)
+        request = quixote.get_request()
         if last_modified == request.get_header('If-Modified-Since'):
             # handle exact match of If-Modified-Since header
             request.response.set_status(304)
@@ -232,7 +234,7 @@
             self.file_class = self.FILE_CLASS
         self.index_filenames = index_filenames
 
-    def _q_index(self, request):
+    def _q_index(self):
         """
         If directory listings are allowed, generate a simple HTML
         listing of the directory's contents with each item hyperlinked;
@@ -242,17 +244,17 @@
         if self.index_filenames:
             for name in self.index_filenames:
                 try:
-                    obj = self._q_lookup(request, name)
+                    obj = self._q_lookup(name)
                 except errors.TraversalError:
                     continue
                 if not isinstance(obj, StaticDirectory) and callable(obj):
-                    return obj(request)
+                    return obj()
         # FIXME: this is not a valid HTML document!
         out = StringIO()
         if self.list_directory:
             template = htmltext('<a href="%s">%s</a>%s')
             print >>out, (htmltext("<h1>%s</h1>")
-                          % request.environ['REQUEST_URI'])
+                          % quixote.get_request().get_environ('REQUEST_URI'))
             print >>out, "<pre>"
             print >>out, template % ('..', '..', '')
             files = os.listdir(self.path)
@@ -269,7 +271,7 @@
                 "<p>This directory does not allow its contents to be listed.</p>"
         return out.getvalue()
 
-    def _q_lookup(self, request, name):
+    def _q_lookup(self, name):
         """
         Get a file from the filesystem directory and return the StaticFile
         or StaticDirectory wrapper of it; use caching if that is in use.
@@ -317,14 +319,16 @@
         self.location = location
         self.permanent = permanent
 
-    def _q_lookup(self, request, component):
+    def _q_lookup(self, component):
         return self
 
-    def __call__(self, request):
-        return request.redirect(self.location, self.permanent)
+    def __call__(self):
+        return quixote.redirect(self.location, self.permanent)
 
 
-def dump_request(request):
+def dump_request(request=None):
+    if request is None:
+        request = quixote.get_request()
     """Dump an HTTPRequest object as HTML."""
     row_fmt = htmltext('<tr><th>%s</th><td>%s</td></tr>')
     r = TemplateIO(html=True)