<commit_before>from collections import defaultdict

from django.http import HttpResponse
from django.template import loader


class hashdict(dict):
    """
    A dict that is hashable. BEWARE not to mutate it..
    """
    def __hash__(self):
        return hash(tuple(sorted(self.items())))

def make_key(expression):
    return hashdict(expression)


class ReportResponse(HttpResponse):
    """
    Ancestor of HttpRespose which takes report class and its args and kwargs
    that renders itself.
    """
    def __init__(self, report_class, *args, **kwargs):
        report = report_class(*args, **kwargs)
        super(ReportResponse, self).__init__(content=report.render(), mimetype=report.mime)
        self['Content-Disposition'] = 'attachment; filename=report.xls'


class Report(object):
    """
    Base class for reporting output.

    Subclasses might (or must) specify the following attributes:

    - columns (required) - column titles for the rendered tables
    - grouping (required)
    - additional_filtering (optional)
    - additional_excludes (optional)

    and methods:

    - get_data (required) - returns the data to be used in the template
    """
    title = None
    columns = None
    aggregation_classes = ()

    def __unicode__(self):
        return self.title

    @property
    def mime(self):
        return 'application/vnd.ms-excel'
<commit_msg>Charset information added to report response (refs #43).<commit_after>from collections import defaultdict

from django.http import HttpResponse
from django.template import loader


class hashdict(dict):
    """
    A dict that is hashable. BEWARE not to mutate it..
    """
    def __hash__(self):
        return hash(tuple(sorted(self.items())))

def make_key(expression):
    return hashdict(expression)


class ReportResponse(HttpResponse):
    """
    Ancestor of HttpRespose which takes report class and its args and kwargs
    that renders itself.
    """
    def __init__(self, report_class, *args, **kwargs):
        report = report_class(*args, **kwargs)
        super(ReportResponse, self).__init__(content=report.render(), content_type=report.contenttype)
        self['Content-Disposition'] = 'attachment; filename=report.xls'


class Report(object):
    """
    Base class for reporting output.

    Subclasses might (or must) specify the following attributes:

    - columns (required) - column titles for the rendered tables
    - grouping (required)
    - additional_filtering (optional)
    - additional_excludes (optional)

    and methods:

    - get_data (required) - returns the data to be used in the template
    """
    title = None
    columns = None
    aggregation_classes = ()

    def __unicode__(self):
        return self.title

    @property
    def contenttype(self):
        return 'application/vnd.ms-excel; charset=utf-8'

{'fraction_non_alphanumeric': 0.09612676056338028, 'fraction_numerical': 0.001056338028169014, 'mean_word_length': 3.2593703148425788, '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': '1270993', 'n_tokens_mistral': 799, 'n_tokens_neox': 769, 'n_words': 246}