0001"""
0002Descriptions of the main interfaces in Wareweb.  These aren't formal
0003interfaces, they are just here for documentation purposes.
0004"""
0005
0006class Attribute(object):
0007    __pudge_visible__ = False
0008    def __init__(self, doc):
0009        self.__doc__ = doc
0010
0011class IServlet:
0012
0013    """
0014    Response method sequence
0015    ------------------------
0016
0017    These methods are called roughly in order to produce the response.
0018    """
0019
0020    def __call__(environ, start_response):
0021        """
0022        Implementation of the WSGI application interface.
0023
0024        Instances of IServlet are WSGI applications.
0025
0026        Calls event ``call`` with ``environ`` and ``start_response``,
0027        which may return (status_headers, app_iter) and thus abort the
0028        rest of the call.
0029        """
0030
0031    def run():
0032        """
0033        'Runs' the request.
0034
0035        This typically just calls ``awake()``, ``respond()`` and
0036        ``sleep()``.  Error handlers could be added here by
0037        subclasses.
0038        
0039        Wrapped as event (wrapped methods call ``start_method_name``
0040        and ``end_method_name``).
0041        """
0042
0043    def awake(call_setup=True):
0044        """
0045        Called at beginning of request.
0046
0047        SHOULD NOT produce output.  If ``call_setup`` is true then
0048        ``.setup()`` will be called.  ``SitePage`` classes (that is,
0049        abstract subclasses of ``Servlet``) should override this
0050        method and not ``setup``.
0051        
0052        Wrapped as event.
0053        """
0054
0055    def setup():
0056        """
0057        Also called at beginning of requests.
0058
0059        Subclasses do not need to call the superclass implementation.
0060        This is where individual (non-abstract) servlets typically do
0061        their setup.
0062        """
0063
0064    def respond():
0065        """
0066        Called after ``.awake()``, this typically produces the body of the response.
0067
0068        Some components may intercept this method (e.g., components
0069        that want to take over the body of the response, like
0070        templating components).  Wrapped as event.
0071        """
0072
0073    def sleep(call_teardown=True):
0074        """
0075        Called at the end of a request, to clean up resources.
0076
0077        Called regardless of exceptions in ``.awake()`` or
0078        ``.respond()``, so implementations should be careful not to
0079        assume all resources have been successfully set up.  Like
0080        ``awake`` this calls ``.teardown()`` if ``call_teardown`` is
0081        true; abstract classes should override this method and not
0082        ``teardown``.
0083
0084        Wrapped as event.
0085        """
0086
0087    def teardown():
0088        """
0089        Resource cleanup at the end of request.
0090
0091        Subclasses do not need to call the superclass implementation.
0092        """
0093
0094    """
0095    Request Attributes
0096    ------------------
0097
0098    These attributes describe the request
0099    """
0100
0101    environ = Attribute("""
0102    The WSGI environment.
0103
0104    Contains typical CGI variables, in addition to any WSGI
0105    extensions.
0106    """)
0107
0108    config = Attribute("""
0109    The Paste configuration object; a dictionary-like object.
0110    """)
0111
0112    app_url = Attribute("""
0113    The URL (usually not fully qualified) of this application.
0114
0115    This looks in the environmental variable ``<app_name>.base_url``.
0116    The default ``app_name`` is ``"app"``, and this requires a
0117    ``urlparser_hook`` in ``__init__.py`` to set accurately, which
0118    would look like::
0119
0120        app_name = 'app'
0121        def urlparse_hook(environ):
0122            key = '%s.base_url' % app_name
0123            if not key in environ:
0124                environ[key] = environ['SCRIPT_NAME']
0125    """)
0126
0127    path_info = Attribute("""
0128    The value of ``environ['PATH_INFO']`` -- all the URL that comes
0129    after this servlet's location.  """)
0130
0131    path_parts = Attribute("""
0132    A list of path parts; essentially ``path_info.split('/')``
0133    """)
0134
0135    fields = Attribute("""
0136    A dictionary-like object of all the request fields (both GET and
0137    POST variables, folded together).
0138
0139    You can also get variables as attributes (which default to None).
0140
0141    Also has a ``.getlist(name)`` method, which returns the variable
0142    as a list (i.e., if missing the return value is ``[]``; if one
0143    string value the return value is ``[value]``)
0144    """)
0145
0146    """
0147    Response Methods
0148    ----------------
0149
0150    These methods are used to create the response
0151    """
0152
0153    title = Attribute("""
0154    Attribute that returns the title of this page.  Default
0155    implementation returns the class's name.
0156    """)
0157
0158    session = Attribute("""
0159    The session object.  This is a dictionary-like object where values
0160    are persisted through multiple requests (using a cookie).
0161    """)
0162
0163    def set_cookie(cookie_name, value, path='/', expires='ONCLOSE',
0164                   secure=False):
0165        """
0166        Creates the named cookie in the response.
0167
0168        ``expires`` can be:
0169        
0170        * ``ONCLOSE`` (default: expires when browser is closed)
0171        * ``NOW`` (for immediate deletion)
0172        * ``NEVER`` (some time far in the future)
0173        * A integer value (expiration in seconds)
0174        * A time.struct_time object
0175        * A string that starts with ``+`` and describes the time, like
0176          ``+1w`` (1 week) or ``+1b`` (1 month)
0177        """
0178
0179    def set_header(header_name, header_value):
0180        """
0181        Sets the named header; overwriting any header that previously
0182        existed.
0183
0184        The ``Status`` header is specially used to change the response
0185        status.
0186        """
0187
0188    def add_header(header_name, header_value):
0189        """
0190        Adds the named header, appending to any previous header that
0191        might have been set.
0192        """
0193
0194    def write(*objs):
0195        """
0196        Writes the objects.
0197
0198        ``None`` is written as the empty string, and unicode objects
0199        are encoded with UTF-8.
0200        """
0201
0202    def redirect(url, **query_vars):
0203        """
0204        Redirects to the given URL.  If the URL is relative, then it
0205        will be resolved to be absolute with respect to
0206        ``self.app_url``.
0207
0208        The status is 303 by default; a status keyword argument can be
0209        passed to override this.
0210
0211        Other variables are appended to the query string, e.g.::
0212
0213            self.redirect('edit', id=5)
0214
0215        Will redirect to ``edit?id=5``
0216        """