diff options
-rw-r--r-- | examples/wsgi/index.html | 3 | ||||
-rw-r--r-- | examples/wsgi/root.html | 7 | ||||
-rw-r--r-- | examples/wsgi/run_wsgi.py | 31 | ||||
-rw-r--r-- | lib/mako/exceptions.py | 156 | ||||
-rw-r--r-- | lib/mako/lookup.py | 7 |
5 files changed, 142 insertions, 62 deletions
diff --git a/examples/wsgi/index.html b/examples/wsgi/index.html new file mode 100644 index 0000000..e38dde4 --- /dev/null +++ b/examples/wsgi/index.html @@ -0,0 +1,3 @@ +<%inherit file="root.html"/> + +This is index.html
\ No newline at end of file diff --git a/examples/wsgi/root.html b/examples/wsgi/root.html new file mode 100644 index 0000000..6b57fc3 --- /dev/null +++ b/examples/wsgi/root.html @@ -0,0 +1,7 @@ +<html> + +<head><title>hi</title></head> +<body> + ${next.body()} +</body> +</html>
\ No newline at end of file diff --git a/examples/wsgi/run_wsgi.py b/examples/wsgi/run_wsgi.py new file mode 100644 index 0000000..029e240 --- /dev/null +++ b/examples/wsgi/run_wsgi.py @@ -0,0 +1,31 @@ +from wsgiutils import wsgiServer +import cgi, sys +from mako.lookup import TemplateLookup +from mako import exceptions + +lookup = TemplateLookup(directories=['./'], filesystem_checks=True) + +def serve(environ, start_response): + fieldstorage = cgi.FieldStorage( + fp = environ['wsgi.input'], + environ = environ, + keep_blank_values = True + ) + d = dict([(k, f[k]) for k in fieldstorage]) + uri = environ.get('PATH_INFO', '/') + + try: + template = lookup.get_template(uri) + start_response("200 OK", [('Content-type','text/html')]) + return [template.render(**d)] + except exceptions.TemplateLookupException: + start_response("404 Not Found", []) + return ["Cant find template '%s'" % uri] + except Exception, e: + start_response("200 OK", [('Content-type','text/html')]) + error_template = exceptions.html_error_template(lookup) + return [error_template.render(error=e)] + +server = wsgiServer.WSGIServer (('localhost', 8000), {'/': serve}) +print "Server listening on port 8000" +server.serve_forever() diff --git a/lib/mako/exceptions.py b/lib/mako/exceptions.py index ff53ba8..3caf025 100644 --- a/lib/mako/exceptions.py +++ b/lib/mako/exceptions.py @@ -36,54 +36,69 @@ class SyntaxException(MakoException): class TemplateLookupException(MakoException): pass -def rich_traceback(): - """format a traceback from sys.exc_info() into 7-item tuples, containing - the regular four traceback tuple items, plus the original template - filename, the line number adjusted relative to the template source, and - code line from that line number of the template.""" - import mako.template - mods = {} - (type, value, trcback) = sys.exc_info() - rawrecords = traceback.extract_tb(trcback) - # this line extends the stack all the way back....shouldnt be needed... - # rawrecords = traceback.extract_stack() + rawrecords - new_trcback = [] - for filename, lineno, function, line in rawrecords: - #print "TB", filename, lineno, function, line - try: - (line_map, template_lines) = mods[filename] - except KeyError: +class RichTraceback(object): + def __init__(self, error): + self.error = error + (self.type, self.value, self.records) = self._init() + if isinstance(error, CompileException) or isinstance(error, SyntaxException): + self.source = file(error.filename).read() + self.lineno = error.lineno + else: + self.source = "" + self.lineno = 0 + self.reverse_records = [r for r in self.records] + self.reverse_records.reverse() + def _init(self): + """format a traceback from sys.exc_info() into 7-item tuples, containing + the regular four traceback tuple items, plus the original template + filename, the line number adjusted relative to the template source, and + code line from that line number of the template.""" + import mako.template + mods = {} + (type, value, trcback) = sys.exc_info() + rawrecords = traceback.extract_tb(trcback) + # this line extends the stack all the way back....shouldnt be needed... + #rawrecords = traceback.extract_stack() + rawrecords + new_trcback = [] + for filename, lineno, function, line in rawrecords: + #print "TB", filename, lineno, function, line try: - info = mako.template._get_module_info(filename) - module_source = info.code - template_source = info.source - template_filename = info.template_filename or filename + (line_map, template_lines) = mods[filename] except KeyError: - new_trcback.append((filename, lineno, function, line, None, None, None, None)) - continue + try: + info = mako.template._get_module_info(filename) + module_source = info.code + template_source = info.source + template_filename = info.template_filename or filename + self.source = template_source + self.lineno = lineno + except KeyError: + new_trcback.append((filename, lineno, function, line, None, None, None, None)) + continue - template_ln = module_ln = 1 - line_map = {} - for line in module_source.split("\n"): - match = re.match(r'\s*# SOURCE LINE (\d+)', line) - if match: - template_ln = int(match.group(1)) - else: - template_ln += 1 - module_ln += 1 - line_map[module_ln] = template_ln - template_lines = [line for line in template_source.split("\n")] - mods[filename] = (line_map, template_lines) + template_ln = module_ln = 1 + line_map = {} + for line in module_source.split("\n"): + match = re.match(r'\s*# SOURCE LINE (\d+)', line) + if match: + template_ln = int(match.group(1)) + else: + template_ln += 1 + module_ln += 1 + line_map[module_ln] = template_ln + template_lines = [line for line in template_source.split("\n")] + mods[filename] = (line_map, template_lines) - template_ln = line_map[lineno] - if template_ln <= len(template_lines): - template_line = template_lines[template_ln - 1] - else: - template_line = None - new_trcback.append((filename, lineno, function, line, template_filename, template_ln, template_line, template_source)) - return (type, value, new_trcback) + template_ln = line_map[lineno] + if template_ln <= len(template_lines): + template_line = template_lines[template_ln - 1] + else: + template_line = None + new_trcback.append((filename, lineno, function, line, template_filename, template_ln, template_line, template_source)) + return (type, value, new_trcback) -def text_error_template(): + +def text_error_template(lookup=None): import mako.template return mako.template.Template(r""" <%! @@ -103,39 +118,62 @@ ${str(type)} - ${value} ${filename} ${lineno} ${line} % endif % endfor -""") +""", lookup=lookup) -def html_error_template(): +def html_error_template(lookup=None): import mako.template return mako.template.Template(r""" <%! - from mako.exceptions import rich_traceback + from mako.exceptions import RichTraceback %> <html> +<head> + <title>Mako Runtime Error</title> + <style> + body { + font-family:verdana; + } + .stacktrace { + margin:10px 30px 10px 30px; + font-size:small; + } + .sample { + + } + </style> +</head> <body> - Error ! + + <h2>Error !</h2> <% - (errtype, value, trcback) = rich_traceback() - src = trcback[-1][7] - line = trcback[-1][5] - lines = src.split('\n') - trcback.reverse() - + tback = RichTraceback(error) + src = tback.source + line = tback.lineno + if src: + lines = src.split('\n') + else: + lines = None %> - +<p> ${str(error)} +</p> -<div> -${'\n'.join(lines[line-5:line+5])} -</div> +% if lines: + <div class="sample"> + ${'\n'.join(lines[line-5:line+5])} + </div> +% endif -% for (filename, lineno, function, line, template_filename, template_ln, template_line, src) in trcback: +<div class="stacktrace"> +% for (filename, lineno, function, line, template_filename, template_ln, template_line, src) in tback.reverse_records: % if template_line: ${template_filename} ${template_ln} ${template_line} <br/> % else: ${filename} ${lineno} ${line}<br/> % endif % endfor +</div> + </body> </html> -""")
\ No newline at end of file +""", lookup=lookup)
\ No newline at end of file diff --git a/lib/mako/lookup.py b/lib/mako/lookup.py index 6babbc7..6bdf586 100644 --- a/lib/mako/lookup.py +++ b/lib/mako/lookup.py @@ -4,7 +4,7 @@ # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import os, stat, posixpath +import os, stat, posixpath, re from mako import exceptions, util from mako.template import Template @@ -43,8 +43,9 @@ class TemplateLookup(TemplateCollection): else: return self.__collection[uri] except KeyError: + u = re.sub(r'^\/+', '', uri) for dir in self.directories: - srcfile = posixpath.join(dir, uri) + srcfile = posixpath.join(dir, u) if os.access(srcfile, os.F_OK): return self.__load(srcfile, uri) else: @@ -75,7 +76,7 @@ class TemplateLookup(TemplateCollection): raise exceptions.TemplateLookupException("Cant locate template for uri '%s'" % uri) elif template.module._modified_time < os.stat(template.filename)[stat.ST_MTIME]: self.__collection.pop(uri, None) - return __load(template.filename, uri) + return self.__load(template.filename, uri) else: return template |