Latest Version: 0.9.6.2
/Users/bbangert/Programming/Python/pylons/pylons/middleware.py
0001"""Pylons' WSGI middlewares"""
0002import logging
0003import os.path
0004import urllib
0005
0006from paste.deploy.converters import asbool
0007from paste.errordocument import StatusBasedForward
0008from paste.recursive import RecursiveMiddleware
0009from paste.urlparser import StaticURLParser
0010
0011from webhelpers.rails.asset_tag import javascript_path
0012
0013__pudge_all__ = ['StaticJavascripts', 'ErrorHandler', 'ErrorDocuments']
0014
0015media_path = os.path.join(os.path.dirname(__file__), 'media')
0016
0017log = logging.getLogger(__name__)
0018
0019
0020class StaticJavascripts(object):
0021    """Middleware for intercepting requests for WebHelpers' included 
0022    javascript files.
0023    
0024    Triggered when PATH_INFO begins with '/javascripts/'.
0025    """
0026    def __init__(self):
0027        self.javascripts_app =               StaticURLParser(os.path.dirname(javascript_path))
0029
0030    def __call__(self, environ, start_response):
0031        if environ.get('PATH_INFO', '').startswith('/javascripts/'):
0032            log.debug("Handling Javascript URL (Starts with /javascripts/)")
0033            return self.javascripts_app(environ, start_response)
0034        else:
0035            return self.javascripts_app.not_found(environ, start_response)
0036
0037
0038def ErrorHandler(app, global_conf, **errorware):
0039    """ErrorHandler Toggle
0040    
0041    If debug is enabled, this function will return the app wrapped in
0042    our customized Paste EvalException middleware we have called the
0043    ``PylonsEvalException``.
0044    
0045    Otherwise, the app will be wrapped in the Paste ErrorMiddleware, and
0046    the ``errorware`` dict will be passed into it.
0047    """
0048    if asbool(global_conf.get('debug')):
0049        from pylons.error import PylonsEvalException
0050        app = PylonsEvalException(app, global_conf, **errorware)
0051    else:
0052        from paste.exceptions.errormiddleware import ErrorMiddleware
0053        if 'error_template' in errorware:
0054            del errorware['error_template']
0055        app = ErrorMiddleware(app, global_conf, **errorware)
0056    return app
0057
0058
0059def error_mapper(code, message, environ, global_conf=None, **kw):
0060    if environ.get('pylons.error_call'):
0061        return None
0062    else:
0063        environ['pylons.error_call'] = True
0064
0065    if global_conf is None:
0066        global_conf = {}
0067    codes = [401, 403, 404]
0068    if not asbool(global_conf.get('debug')):
0069        codes.append(500)
0070    if code in codes:
0071        # StatusBasedForward expects a relative URL (no SCRIPT_NAME)
0072        url = '/error/document/?%s' % (urllib.urlencode({'message': message,
0073                                                         'code': code}))
0074        return url
0075
0076
0077def ErrorDocuments(app, global_conf=None, mapper=None, **kw):
0078    """Wraps the app in error docs using Paste RecursiveMiddleware and
0079    ErrorDocumentsMiddleware
0080    
0081    All the args are passed directly into the ErrorDocumentsMiddleware. If no
0082    mapper is given, a default error_mapper is passed in.
0083    """
0084    if global_conf is None:
0085        global_conf = {}
0086    if mapper is None:
0087        mapper = error_mapper
0088    return RecursiveMiddleware(StatusBasedForward(app, global_conf=global_conf,
0089                                                  mapper=mapper, **kw))
0090
0091
0092error_document_template = """\
0093<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
0094<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
0095<head>
0096 <title>Server Error %(code)s</title>
0097 
0098<style type="text/css">
0099body {
0100  font-family: Helvetica, sans-serif;
0101}
0102
0103table {
0104  width: 100%%;
0105}
0106
0107tr.header {
0108  background-color: #006;
0109  color: #fff;
0110}
0111
0112tr.even {
0113  background-color: #ddd;
0114}
0115
0116table.variables td {
0117  verticle-align: top;
0118  overflow: auto;
0119}
0120
0121a.button {
0122  background-color: #ccc;
0123  border: 2px outset #aaa;
0124  color: #000;
0125  text-decoration: none;
0126}
0127
0128a.button:hover {
0129  background-color: #ddd;
0130}
0131
0132code.source {
0133  color: #006;
0134}
0135
0136a.switch_source {
0137  color: #0990;
0138  text-decoration: none;
0139}
0140
0141a.switch_source:hover {
0142  background-color: #ddd;
0143}
0144
0145.source-highlight {
0146  background-color: #ff9;
0147}
0148
0149</style>
0150
0151<!-- CSS Imports -->
0152<link rel="stylesheet" href="%(prefix)s/error/style/orange.css" type="text/css" media="screen" />
0153
0154<!-- Favorite Icons -->
0155<link rel="icon" href="%(prefix)s/error/img/icon-16.png" type="image/png" />
0156
0157<style type="text/css">
0158        .red {
0159            color:#FF0000;
0160        }
0161        .bold {
0162            font-weight: bold;
0163        }
0164</style>
0165
0166</head>
0167
0168<body id="documentation">
0169<!-- We are only using a table to ensure old browsers see the message correctly -->
0170
0171<noscript>
0172<div style="border-bottom: 1px solid #808080">
0173<div style="border-bottom: 1px solid #404040">
0174<table width="100%%" border="0" cellpadding="0" bgcolor="#FFFFE1"><tr><td valign="middle"><img src="%(prefix)s/error/img/warning.gif" alt="Warning" /></td><td>&nbsp;</td><td><span style="padding: 0px; margin: 0px; font-family: Tahoma, sans-serif; font-size: 11px">Warning, your browser does not support JavaScript so you will not be able to use the interactive debugging on this page.</span></td></tr></table>
0175</div>
0176</div>
0177</noscript>
0178    
0179    <!-- Top anchor -->
0180    <a name="top"></a>
0181    
0182    <!-- Logo -->
0183    <h1 id="logo"><a class="no-underline" href="http://www.pylonshq.com"><img class="no-border" src="%(prefix)s/error/img/logo.gif" alt="Pylons" title="Pylons"/></a></h1>
0184    <p class="invisible"><a href="#content">Skip to content</a></p>
0185
0186    <!-- Main Content -->
0187
0188    <div id="nav-bar">
0189
0190        <!-- Section Navigation -->
0191        <h4 class="invisible">Section Links</h4>
0192
0193            <ul id="navlist">
0194                <li class="active"><a href="#" accesskey="1" class="active">Error %(code)s</a></li>
0195            </ul>
0196    </div>
0197    <div id="main-content">
0198    
0199        <div class="hr"><hr class="hr" /></div> 
0200
0201        <div class="content-padding">
0202            
0203            <div id="main_data">
0204                <div style="float: left; width: 100%%; padding-bottom: 20px;">
0205                <h1 class="first"><a name="content"></a>Error %(code)s</h1>
0206                </div>
0207                
0208                %(message)s
0209                
0210            </div>
0211
0212        </div>
0213        
0214        
0215            <!-- Footer -->
0216
0217        <div class="hr"><hr class="clear" /></div>
0218    </div>
0219    
0220    <div style=" background: #FFFF99; padding: 10px 10px 10px 6%%; clear: both;">
0221        The Pylons Team | 
0222        <a href="#top" accesskey="9" title="Return to the top of the navigation links">Top</a>
0223    </div>
0224</body>
0225</html>
0226"""

Top