Example #1
0
    def template_has_valid_syntax(self, template_name):
        from otree.checks.templates import has_valid_encoding
        from otree.checks.templates import format_source_snippet

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                Template(f.read())
        except (IOError, OSError):
            pass
        except TemplateSyntaxError as error:
            # The django_template_source attribute will only be available on
            # DEBUG = True.
            if hasattr(error, 'django_template_source'):
                template_source, position = error.django_template_source
                snippet = format_source_snippet(template_source.source,
                                                arrow_position=position[0])
                message = ('Template syntax error in {template}\n'
                           '\n'
                           '{snippet}\n'
                           '\n'
                           'Error: {error}'.format(template=template_name,
                                                   error=error,
                                                   snippet=snippet))
            else:
                message = ('Template syntax error in {template}\n'
                           'Error: {error}\n'
                           'Set "DEBUG = True" to see more details.'.format(
                               template=template_name, error=error))
            return self.error(message)
Example #2
0
    def template_has_no_dead_code(self, template_name):
        from otree.checks.templates import get_unreachable_content
        from otree.checks.templates import has_valid_encoding

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                compiled_template = Template(f.read())
        except (IOError, OSError, TemplateSyntaxError):
            # Ignore errors that occured during file-read or compilation.
            return

        def format_content(text):
            text = text.strip()
            lines = text.splitlines()
            lines = ['> {0}'.format(line) for line in lines]
            return '\n'.join(lines)

        contents = get_unreachable_content(compiled_template)
        content_bits = '\n\n'.join(format_content(bit) for bit in contents)
        if contents:
            return self.error(
                'Template contains the following text outside of a '
                '{% block %}. This text will never be displayed.'
                '\n\n' + content_bits,
                obj=os.path.join(self.config.label,
                                 self.get_rel_path(template_name)))
Example #3
0
    def template_has_no_dead_code(self, template_name):
        from otree.checks.templates import get_unreachable_content
        from otree.checks.templates import has_valid_encoding

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                compiled_template = Template(f.read())
        except (IOError, OSError, TemplateSyntaxError):
            # Ignore errors that occured during file-read or compilation.
            return

        def format_content(text):
            text = text.strip()
            lines = text.splitlines()
            lines = ['> {0}'.format(line) for line in lines]
            return '\n'.join(lines)

        contents = get_unreachable_content(compiled_template)
        content_bits = '\n\n'.join(
            format_content(bit)
            for bit in contents)
        if contents:
            return self.error(
                'Template contains the following text outside of a '
                '{% block %}. This text will never be displayed.'
                '\n\n' + content_bits,
                obj=os.path.join(self.config.label,
                                 self.get_rel_path(template_name)))
Example #4
0
    def template_has_valid_syntax(self, template_name):
        from otree.checks.templates import has_valid_encoding
        from otree.checks.templates import format_source_snippet

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                Template(f.read())
        except (IOError, OSError):
            pass
        except TemplateSyntaxError as error:
            template_source, position = error.django_template_source
            snippet = format_source_snippet(
                template_source.source,
                arrow_position=position[0])
            return self.error(
                'Template syntax error in {template}\n'
                '\n'
                '{snippet}\n'
                '\n'
                'Error: {error}'.format(
                    template=template_name,
                    error=error,
                    snippet=snippet))
Example #5
0
def template_valid(template_name: str, helper: AppCheckHelper):
    from otree.checks.templates import get_unreachable_content
    from otree.checks.templates import has_valid_encoding
    from otree.checks.templates import format_source_snippet

    # Only test files that are valid templates.
    if not has_valid_encoding(template_name):
        return

    try:
        with io.open(template_name, 'r', encoding='utf8') as f:
            compiled_template = Template(f.read())
    except (IOError, OSError, TemplateSyntaxError):
        # When we used Django 1.8
        # we used to show the line from the source that caused the error,
        # but django_template_source was removed at some point,
        # so it's better to let the yellow error page show the error nicely
        return

    def format_content(text):
        text = text.strip()
        lines = text.splitlines()
        lines = ['> {0}'.format(line) for line in lines]
        return '\n'.join(lines)

    contents = get_unreachable_content(compiled_template)
    content_bits = '\n\n'.join(format_content(bit) for bit in contents)
    if contents:
        helper.add_error('Template contains the following text outside of a '
                         '{% block %}. This text will never be displayed.'
                         '\n\n' + content_bits,
                         obj=os.path.join(helper.app_config.label,
                                          helper.get_rel_path(template_name)),
                         numeric_id=7)
Example #6
0
    def template_has_valid_encoding(self, template_name):
        from otree.checks.templates import has_valid_encoding

        if not has_valid_encoding(template_name):
            return self.error(
                'The template {template} is not UTF-8 encoded. '
                'Please configure your text editor to always save files '
                'as UTF-8. Then open the file and save it again.'.format(
                    template=self.get_rel_path(template_name)))
Example #7
0
    def template_has_valid_encoding(self, template_name):
        from otree.checks.templates import has_valid_encoding

        if not has_valid_encoding(template_name):
            return self.error(
                'The template {template} is not UTF-8 encoded. '
                'Please configure your text editor to always save files '
                'as UTF-8. Then open the file and save it again.'
                .format(template=self.get_rel_path(template_name)))
Example #8
0
def template_content_is_in_blocks(template_name: str, helper: AppCheckHelper):
    from otree.checks.templates import get_unreachable_content
    from otree.checks.templates import has_valid_encoding
    from otree.checks.templates import format_source_snippet

    # Only test files that are valid templates.
    if not has_valid_encoding(template_name):
        return

    try:
        with io.open(template_name, 'r', encoding='utf8') as f:

            # when we upgraded to Django 1.11, we got an error
            # if someone used "{% include %}" with a relative
            # path (like ../Foo.html):
            # File "c:\otree\ve_dj11\lib\site-packages\django\template\loader_tags.py", line 278, in construct_relative_path
            #  posixpath.dirname(current_template_name.lstrip('/')),
            # AttributeError: 'NoneType' object has no attribute 'lstrip'
            # can fix this by passing a dummy 'Origin' param.
            # i tried also with Engin.get_default().from_string(template_name),
            # but got the same error.
            class Origin:
                name = ''
                template_name = ''

            compiled_template = Template(f.read(), origin=Origin)
    except (IOError, OSError, TemplateSyntaxError):
        # When we used Django 1.8
        # we used to show the line from the source that caused the error,
        # but django_template_source was removed at some point,
        # so it's better to let the yellow error page show the error nicely
        return

    def format_content(text):
        text = text.strip()
        lines = text.splitlines()
        lines = ['> {0}'.format(line) for line in lines]
        return '\n'.join(lines)

    contents = get_unreachable_content(compiled_template)

    content_bits = '\n\n'.join(
        format_content(bit)
        for bit in contents)
    # note: this seems to not detect unreachable content
    # if the template has a relative include,
    # like {% include "../Foo.html" %}
    # not sure why, but that's not common usage.
    if contents:
        helper.add_error(
            'Template contains the following text outside of a '
            '{% block %}. This text will never be displayed.'
            '\n\n' + content_bits,
            obj=os.path.join(helper.app_config.label,
                             helper.get_rel_path(template_name)),
            numeric_id=7)
Example #9
0
def template_encoding(helper: AppCheckHelper, **kwargs):
    from otree.checks.templates import has_valid_encoding
    for template_name in helper.get_template_names():
        if not has_valid_encoding(template_name):
            helper.add_error(
                'The template {template} is not UTF-8 encoded. '
                'Please configure your text editor to always save files '
                'as UTF-8. Then open the file and save it again.'
                    .format(template=helper.get_rel_path(template_name)),
                numeric_id=60,
            )
Example #10
0
def no_model_class_references(helper: AppCheckHelper, **kwargs):
    models_path = helper.get_path('models.py')

    from otree.checks.templates import has_valid_encoding

    # Only test files that are valid templates.
    if not has_valid_encoding(models_path):
        return

    try:
        with io.open(models_path, 'r', encoding='utf8') as f:
            content = f.read()
    except (IOError, OSError):
        # when would these errors occur?
        # (this was originally copied from template check)
        return

    allowed_attr_names = ['add_to_class', 'objects']
    matches = re.finditer(r'(Player|Group|Subsession)\.(\w+)', content)

    for m in matches:
        matched_text = m.group(0)
        ModelName = m.group(1)
        attr_name = m.group(2)
        if attr_name in allowed_attr_names:
            continue
        position = m.start(0)
        num_newlines = content[:position].count('\n')
        line_number = num_newlines + 1
        first_letter_uppercase = ModelName[0]
        helper.add_error(
            f'models.py contains a reference to "{matched_text}" around line {line_number}. '
            f'You should not refer to {ModelName} with an uppercase {ModelName[0]}, '
            f'because that refers to the whole class, '
            f'rather than any individual {ModelName.lower()}. '
            'Learn about how to access instances using "self".',
            numeric_id=120)
Example #11
0
    def template_has_valid_syntax(self, template_name):
        from otree.checks.templates import has_valid_encoding
        from otree.checks.templates import format_source_snippet

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                Template(f.read())
        except (IOError, OSError):
            pass
        except TemplateSyntaxError as error:
            # The django_template_source attribute will only be available on
            # DEBUG = True.
            if hasattr(error, 'django_template_source'):
                template_source, position = error.django_template_source
                snippet = format_source_snippet(
                    template_source.source,
                    arrow_position=position[0])
                message = (
                    'Template syntax error in {template}\n'
                    '\n'
                    '{snippet}\n'
                    '\n'
                    'Error: {error}'.format(
                        template=template_name,
                        error=error,
                        snippet=snippet))
            else:
                message = (
                    'Template syntax error in {template}\n'
                    'Error: {error}\n'
                    'Set "DEBUG = True" to see more details.'.format(
                        template=template_name, error=error))
            return self.error(message)
Example #12
0
    def template_has_valid_syntax(self, template_name):
        from otree.checks.templates import has_valid_encoding
        from otree.checks.templates import format_source_snippet

        # Only test files that are valid templates.
        if not has_valid_encoding(template_name):
            return

        try:
            with open(template_name, 'r') as f:
                Template(f.read())
        except (IOError, OSError):
            pass
        except TemplateSyntaxError as error:
            template_source, position = error.django_template_source
            snippet = format_source_snippet(template_source.source,
                                            arrow_position=position[0])
            return self.error('Template syntax error in {template}\n'
                              '\n'
                              '{snippet}\n'
                              '\n'
                              'Error: {error}'.format(template=template_name,
                                                      error=error,
                                                      snippet=snippet))
Example #13
0
 def test_good_encoding(self):
     file_name = os.path.join(TEST_DIR, 'test_files',
                              'good_encoding_template.html')
     self.assertTrue(has_valid_encoding(file_name))
Example #14
0
 def test_good_encoding(self):
     file_name = os.path.join(TEST_DIR, 'test_files',
                              'good_encoding_template.html')
     self.assertTrue(has_valid_encoding(file_name))