app/django/template/debug.py
author Lennard de Rijk <ljvderijk@gmail.com>
Mon, 16 Feb 2009 20:38:35 +0000
changeset 1364 b2709805fafe
parent 54 03e267d67478
permissions -rw-r--r--
Update org bulk accept script. The script now: 1) leaves correctly control to the browser to update the GUI of the progress bar during ajax communication. 2) Displays an error if something went wrong (I've tried in my box stopping the server while doing the requests), and show a retry button to fetch again the list of the applications that are still not accepted and iterate over them again (seems to recover correctly restarting the server after the error in my box) 3) doesn't display any text at the beginning, and the button has the correct CSS class assigned 4) Check if there are applications to accept, if not displays a message stating that there are no orgs to accept. Patch by: Mario Ferraro Reviewed by: Lennard de Rijk

from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
from django.utils.encoding import force_unicode
from django.utils.html import escape
from django.utils.safestring import SafeData, EscapeData

class DebugLexer(Lexer):
    def __init__(self, template_string, origin):
        super(DebugLexer, self).__init__(template_string, origin)

    def tokenize(self):
        "Return a list of tokens from a given template_string"
        result, upto = [], 0
        for match in tag_re.finditer(self.template_string):
            start, end = match.span()
            if start > upto:
                result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
                upto = start
            result.append(self.create_token(self.template_string[start:end], (start, end), True))
            upto = end
        last_bit = self.template_string[upto:]
        if last_bit:
            result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
        return result

    def create_token(self, token_string, source, in_tag):
        token = super(DebugLexer, self).create_token(token_string, in_tag)
        token.source = self.origin, source
        return token

class DebugParser(Parser):
    def __init__(self, lexer):
        super(DebugParser, self).__init__(lexer)
        self.command_stack = []

    def enter_command(self, command, token):
        self.command_stack.append( (command, token.source) )

    def exit_command(self):
        self.command_stack.pop()

    def error(self, token, msg):
        return self.source_error(token.source, msg)

    def source_error(self, source,msg):
        e = TemplateSyntaxError(msg)
        e.source = source
        return e

    def create_nodelist(self):
        return DebugNodeList()

    def create_variable_node(self, contents):
        return DebugVariableNode(contents)

    def extend_nodelist(self, nodelist, node, token):
        node.source = token.source
        super(DebugParser, self).extend_nodelist(nodelist, node, token)

    def unclosed_block_tag(self, parse_until):
        command, source = self.command_stack.pop()
        msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
        raise self.source_error(source, msg)

    def compile_function_error(self, token, e):
        if not hasattr(e, 'source'):
            e.source = token.source

class DebugNodeList(NodeList):
    def render_node(self, node, context):
        try:
            result = node.render(context)
        except TemplateSyntaxError, e:
            if not hasattr(e, 'source'):
                e.source = node.source
            raise
        except Exception, e:
            from sys import exc_info
            wrapped = TemplateSyntaxError(u'Caught an exception while rendering: %s' % force_unicode(e, errors='replace'))
            wrapped.source = node.source
            wrapped.exc_info = exc_info()
            raise wrapped
        return result

class DebugVariableNode(VariableNode):
    def render(self, context):
        try:
            output = force_unicode(self.filter_expression.resolve(context))
        except TemplateSyntaxError, e:
            if not hasattr(e, 'source'):
                e.source = self.source
            raise
        except UnicodeDecodeError:
            return ''
        if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
            return escape(output)
        else:
            return output