<commit_before>import json
import mimeparse
import inspect

from jinja2 import Template, DebugUndefined, Environment, PackageLoader
from jinja2.exceptions import TemplateNotFound

from giotto import get_config
from giotto.exceptions import NoViewMethod
from giotto.utils import Mock, htmlize, htmlize_list, pre_process_json, super_accept_to_mimetype, jsonify
from giotto.control import GiottoControl

def renders(*mimetypes):
    def decorator(func):
        func.mimetypes = []
        for mimetype in mimetypes:
            func.mimetypes.append(mimetype)
        return func
    return decorator

class GiottoView(object):
    """
    Base class for all Giotto view objects. All Giotto Views must at least descend
    from this class, as ths class contains piping that the controller calls.
    """

    def __init__(self, persist=None, **kwargs):
        self.persist = persist
        self.render_map = {} # renderers by mimetype
        self.reject_map = {} # renderers by name (no corresponding mimetype)
        class_defined_renderers = [x for x in dir(self) if not x.startswith('__')]
        self._register_renderers(class_defined_renderers)

        for format, function in kwargs.items():
            ## key word arguments can be passed into the constructor to
            ## override render methods from within the manifest.
            ## set 'mimetypes' as if it were using the @renders decorator
            mime = super_accept_to_mimetype(format)
            setattr(function, 'mimetypes', [mime or format])
            setattr(self, format, function)

        # kwarg renderers kill any render methods that are defined by the class
        self._register_renderers(kwargs.keys())

    def _register_renderers(self, attrs):
        """
        Go through the passed in list of attributes and register those renderers
        in the render map.
        """
        for method in attrs:
            func = getattr(self, method)
            mimetypes = getattr(func, 'mimetypes', [])
            for mimetype in mimetypes:
                if not '/' in mimetype:
                    self.reject_map[mimetype] = func
                if mimetype not in self.render_map:
                    self.render_map[mimetype] = func
                else:
                    # about to redefine an already defined renderer.
                    # make sure this new render method is not on a base class.
                    base_classes = self.__class__.mro()[1:]
                    from_baseclass = any([x for x in base_classes if func.__name__ in dir(x)])
                    if not from_baseclass:
                        self.render_map[mimetype] = func


    def can_render(self, partial_mimetype):
        """
        Given a partial mimetype (such as 'json' or 'html'), return if the 
        view can render that type.
        """
        for mime in self.render_map.keys():
            if mime == '*/*':
                return True
            if partial_mimetype in mime:
                return True
        return False

    def render(self, result, mimetype, errors=None):
        """
        Render a model result into `mimetype` format.
        """
        available_mimetypes = self.render_map.keys()
        render_func = None

        if '/' not in mimetype:
            # naked superformat (does not correspond to a mimetype)
            render_func = self.reject_map.get(mimetype, None)
            if not render_func:
                raise NoViewMethod("Unknown Superformat: %s" % mimetype)

        if not render_func and available_mimetypes:
            target_mimetype = mimeparse.best_match(available_mimetypes, mimetype)
            render_func = self.render_map.get(target_mimetype, None)

        if not render_func:
            raise NoViewMethod("%s not supported for this program" % mimetype)

        principle_mimetype = render_func.mimetypes[0]

        if GiottoControl in render_func.__class__.mro():
            # redirection defined as view (not wrapped in lambda)
            return {'body': render_func, 'persist': render_func.persist}<commit_msg>fixed bug where invalid mimetypes were messing up mimetype negotiation<commit_after>import json
import mimeparse
import inspect

from jinja2 import Template, DebugUndefined, Environment, PackageLoader
from jinja2.exceptions import TemplateNotFound

from giotto import get_config
from giotto.exceptions import NoViewMethod
from giotto.utils import Mock, htmlize, htmlize_list, pre_process_json, super_accept_to_mimetype, jsonify
from giotto.control import GiottoControl

def renders(*mimetypes):
    def decorator(func):
        func.mimetypes = []
        for mimetype in mimetypes:
            func.mimetypes.append(mimetype)
        return func
    return decorator

class GiottoView(object):
    """
    Base class for all Giotto view objects. All Giotto Views must at least descend
    from this class, as ths class contains piping that the controller calls.
    """

    def __init__(self, persist=None, **kwargs):
        self.persist = persist
        self.render_map = {} # renderers by mimetype
        self.reject_map = {} # renderers by name (no corresponding mimetype)
        class_defined_renderers = [x for x in dir(self) if not x.startswith('__')]
        self._register_renderers(class_defined_renderers)

        for format, function in kwargs.items():
            ## key word arguments can be passed into the constructor to
            ## override render methods from within the manifest.
            ## set 'mimetypes' as if it were using the @renders decorator
            mime = super_accept_to_mimetype(format)
            setattr(function, 'mimetypes', [mime or format])
            setattr(self, format, function)

        # kwarg renderers kill any render methods that are defined by the class
        self._register_renderers(kwargs.keys())

    def _register_renderers(self, attrs):
        """
        Go through the passed in list of attributes and register those renderers
        in the render map.
        """
        for method in attrs:
            func = getattr(self, method)
            mimetypes = getattr(func, 'mimetypes', [])
            for mimetype in mimetypes:
                if not '/' in mimetype:
                    self.reject_map[mimetype] = func
                if mimetype not in self.render_map:
                    self.render_map[mimetype] = func
                else:
                    # about to redefine an already defined renderer.
                    # make sure this new render method is not on a base class.
                    base_classes = self.__class__.mro()[1:]
                    from_baseclass = any([x for x in base_classes if func.__name__ in dir(x)])
                    if not from_baseclass:
                        self.render_map[mimetype] = func


    def can_render(self, partial_mimetype):
        """
        Given a partial mimetype (such as 'json' or 'html'), return if the 
        view can render that type.
        """
        for mime in self.render_map.keys():
            if mime == '*/*':
                return True
            if partial_mimetype in mime:
                return True
        return False

    def render(self, result, mimetype, errors=None):
        """
        Render a model result into `mimetype` format.
        """
        available_mimetypes = [x for x in self.render_map.keys() if '/' in x]
        render_func = None

        if '/' not in mimetype:
            # naked superformat (does not correspond to a mimetype)
            render_func = self.reject_map.get(mimetype, None)
            if not render_func:
                raise NoViewMethod("Unknown Superformat: %s" % mimetype)

        if not render_func and available_mimetypes:
            target_mimetype = mimeparse.best_match(available_mimetypes, mimetype)
            render_func = self.render_map.get(target_mimetype, None)

        if not render_func:
            raise NoViewMethod("%s not supported for this program" % mimetype)

        principle_mimetype = render_func.mimetypes[0]

        if GiottoControl in render_func.__class__.mro():
            # redirection defined as view (not wrapped in lambda)
            return {'body': render_func, 'persist': render_func.persist}
{'fraction_non_alphanumeric': 0.0725181598062954, 'fraction_numerical': 0.0009685230024213075, 'mean_word_length': 2.238337906703254, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6115012', 'n_tokens_mistral': 2272, 'n_tokens_neox': 2223, 'n_words': 737}