Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added pretty error template gist and setup changes

  • Loading branch information...
commit cdd98c67c026df96a1ea698b19aa97ce4de3cc7d 1 parent d0e18be
LBiNationalTrust LBiNationalTrust authored
3  Mojo/RequestHandlers/MojoHandler.py
View
@@ -5,10 +5,11 @@
from tornado.web import RequestHandler
import datetime, logging, os
from tornado import gen
+from Mojo.RequestHandlers.PrettyOutputMixin import UncaughtExceptionMixin
from Mojo.Auth.models import Session, User
-class MojoRequestHandler(RequestHandler):
+class MojoRequestHandler(RequestHandler, UncaughtExceptionMixin):
"""
The ``MojoRequestHandler`` is the starting point of any request in Mojo, subclass this for every URL
you want to serve in Mojo.
61 Mojo/RequestHandlers/PrettyOutputMixin.py
View
@@ -0,0 +1,61 @@
+#Modified version of Phil Plante's prettified output to work with a Mojo installation
+
+#Source: http://tornadogists.org/911930/
+# Copyright (c) 2011 Phil Plante <unhappyrobot AT gmail DOT com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import httplib
+import logging
+import os
+import Mojo
+
+exception_template = os.path.dirname(Mojo.__file__) + '/Resources/MojoTemplates/exception.html'
+
+class UncaughtExceptionMixin(object):
+ def get_error_html(self, status_code, **kwargs):
+ def get_snippet(fp, target_line, num_lines):
+ if fp.endswith('.html'):
+ fp = os.path.join(self.get_template_path(), fp)
+
+ half_lines = (num_lines/2)
+ try:
+ with open(fp) as f:
+ all_lines = [line for line in f]
+
+ return ''.join(all_lines[target_line-half_lines:target_line+half_lines])
+ except Exception, ex:
+ logging.error(ex)
+
+ return ''
+
+ if self.application.settings.get('debug', False) is False:
+ full_message = kwargs.get('exception', None)
+ if not full_message or unicode(full_message) == '':
+ full_message = 'Sky is falling!'
+
+ return "<html><title>%(code)d: %(message)s</title><body><h1>%(code)d: %(message)s</h1>%(full_message)s</body></html>" % {
+ "code": status_code,
+ "message": httplib.responses[status_code],
+ "full_message": full_message,
+ }
+ else:
+ exception = kwargs.get('exception', None)
+
+ return self.render_string(exception_template, get_snippet=get_snippet, exception=exception, status_code=status_code, kwargs=kwargs)
211 Mojo/Resources/MojoTemplates/exception.html
View
@@ -0,0 +1,211 @@
+<!--
+
+# Copyright (c) 2011 Phil Plante <unhappyrobot AT gmail DOT com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+-->
+{% import traceback %}
+{% import sys %}
+{% import os %}
+{% import tornado %}
+
+{% set type, value, tback = sys.exc_info() %}
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+ <title>HTTP Status {{ status_code }} &raquo; Tornado v{{ tornado.version }}</title>
+ <link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
+
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript" charset="utf-8"></script>
+ <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script>
+ <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js" type="text/javascript"></script>
+ <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript"></script>
+ <script type="text/javascript" charset="utf-8">
+ SyntaxHighlighter.all();
+ </script>
+ <style type="text/css" media="screen">
+ body {
+ font-family: Helvetica;
+ font-size: 10pt;
+ }
+
+ h1 {
+ background: #ffc06f;
+ border-bottom: 1px solid #ff9309;
+ margin: 0;
+ padding: 5px;
+ }
+
+ h2 {
+ background: #ffdd6f;
+ border-bottom: 1px solid #ff9309;
+ margin: 0;
+ margin-bottom: 1em;
+ padding: 5px;
+ }
+
+ h3 {
+ border-bottom: 1px solid #CCC;
+ margin: 0.5em 0;
+ padding-bottom: 0.5em;
+ }
+
+ hr {
+ background: #CCC;
+ border: none;
+ height: 1px;
+ margin: 0.25em 0;
+ }
+
+ .traceback-frame-header td {
+ background: #EEFFFF;
+ padding: 5px;
+ }
+
+ .traceback-frame-header h4 {
+ cursor: pointer;
+ margin: 0;
+ }
+
+ .traceback-frame.first .traceback-frame-header td {
+ background: #e8fce4;
+ }
+
+ table td.key {
+ background: #E9FFFF;
+ padding: 4px 8px;
+ }
+
+ table td.value {
+ padding: 4px;
+ }
+
+ table td.value.alt {
+ background: #EFEFEF;
+ }
+ </style>
+</head>
+
+<body>
+
+<h1>HTTP Status {{ status_code }}</h1>
+
+{% if exception %}
+{% set traceback_list = traceback.extract_tb(tback) %}
+<h2>Application raised {{ exception.__class__.__name__ }}: {{ exception }}</h2>
+{% set filepath, line, method, code = traceback_list[-1] %}
+<table class="traceback-frame first">
+ <tr class="traceback-frame-header">
+ <td width="100%" nowrap>
+ <h4>on line <span class="line-no">{{ line }}</span> of <span class="method">{{ method }}</span> in {{ os.path.basename(filepath) }}</h4>
+ </td>
+ <td nowrap>File: <strong>{{ filepath }}</strong></td>
+ </tr>
+ <tr class="traceback-frame-extended">
+ <td colspan="2">
+ {% set extension = os.path.splitext(filepath)[1][1:] %}
+ {% if extension in ['py', 'html', 'htm'] %}
+ <pre class="brush: {{ os.path.splitext(filepath)[1][1:] }}; ruler: true; toolbar: false; smart-tabs: true; first-line: {{ line-4 }}; highlight: {{ line }};">
+ {{ escape(get_snippet(filepath, line, 10)) }}
+ </pre>
+ {% else %}
+ <p>Cannot load file, type not supported.</p>
+ {% end %}
+ </td>
+ </tr>
+</table>
+<br />
+
+<h3>Full Traceback</h3>
+<sup>click each row to view full detail and source code snippet.</sup>
+<div id="full-traceback">
+ {% for filepath, line, method, code in traceback_list %}
+ <table class="traceback-frame">
+ <tr class="traceback-frame-header">
+ <td width="100%" nowrap>
+ <h4>on line <span class="line-no">{{ line }}</span> of <span class="method">{{ method }}</span> in {{ os.path.basename(filepath) }}</h4>
+ </td>
+ <td nowrap>File: <strong>{{ filepath }}</strong></td>
+ </tr>
+ <tr class="traceback-frame-extended">
+ <td colspan="2">
+ {% set extension = os.path.splitext(filepath)[1][1:] %}
+ {% if extension in ['py', 'html', 'htm'] %}
+ <pre class="brush: {{ os.path.splitext(filepath)[1][1:] }}; ruler: true; toolbar: false; smart-tabs: true; first-line: {{ line-4 }}; highlight: {{ line }};">
+ {{ escape(get_snippet(filepath, line, 10)) }}
+ </pre>
+ {% else %}
+ <p>Cannot load file, type not supported.</p>
+ {% end %}
+ </td>
+ </tr>
+ </table>
+ <br />
+ {% end %}
+</div>
+
+<h3>Request Headers</h3>
+<p>
+<table width="100%">
+ {% for hk, hv in handler.request.headers.iteritems() %}
+ <tr>
+ <td class="key" nowrap>{{ hk }}</td>
+ <td class="value" width="100%">{{ hv }}</td>
+ </tr>
+ {% end %}
+</table>
+</p>
+
+<br />
+
+<h3>Response Headers</h3>
+<p>
+<table width="100%">
+ {% for hk, hv in handler._headers.iteritems() %}
+ <tr>
+ <td class="key" nowrap>{{ hk }}</td>
+ <td class="value" width="100%">{{ hv }}</td>
+ </tr>
+ {% end %}
+</table>
+</p>
+{% end %}
+
+<br />
+<br />
+<hr />
+
+<p>
+ Tornado v{{ tornado.version }}
+</p>
+
+<script type="text/javascript" charset="utf-8">
+ $(document).ready(function(e) {
+ $('#full-traceback .traceback-frame-extended').hide();
+ $('#full-traceback .traceback-frame-header').click(function(e) {
+ $(e.currentTarget).siblings('.traceback-frame-extended').toggle();
+ });
+ })
+</script>
+</body>
+</html>
3  Mojo/mojo_manager.py
View
@@ -4,9 +4,6 @@
import os, sys
import shutil
-#TODO: Remove this
-sys.path.append('/Users/buhrm/src/DynaMojoEnv/')
-
import Mojo
project_files = [
1  SampleMojoProject/Apps/Admin/views.py
View
@@ -18,6 +18,7 @@ def get(self):
a = yield gen.Task(self.get_session_key,'logged_in')
print 'YIELED STSTEMENT: ', a
+
if self.current_user:
self.render('login.html', error='ALREADY LOGGED IN')
else:
2  SampleMojoProject/Apps/SampleApp/views.py
View
@@ -4,6 +4,4 @@
class myRequestHandler(MojoRequestHandler):
def get(self):
-
-
self.render('test.html', message='Your face')
3  setup.py
View
@@ -21,7 +21,8 @@
'Mojo.ServerHelpers',
'Mojo.SocketHandlers'
],
- package_data={'Mojo': ['Resources/Project/Apps/templates/*.html']},
+ package_data={'Mojo': ['Resources/Project/Apps/templates/*.html',
+ 'Resources/MojoTemplates/exception.html']},
requires=['Tornado',
'tornadio2',
'pymongo',
Please sign in to comment.
Something went wrong with that request. Please try again.