<commit_before>from django.db import models


NULL_DISPLAY = "&ndash;"


class ChartCell(object):
    head_attrs = {}
    body_attrs = {}
    label = ""
    format = "%s"
    text = ""
    raw_text = ""

    def __init__(self, cls, fieldname, format=None):
        self.label = fieldname
        try:
            self.field = cls._meta.get_field(fieldname)
            self.text = self.field.verbose_name
        except models.FieldDoesNotExist:
            self.text = fieldname
        self.raw_text = self.text
        if format is not None:
            self.format = format
        if hasattr(cls, 'chart_head_attrs'):
            self.head_attrs = dict(cls.chart_head_attrs)
        if hasattr(cls, 'chart_body_attrs'):
            self.body_attrs = dict(cls.chart_body_attrs)

    def apply_format(self, template):
        try:
            return template % self.raw_text
        except TypeError:
            return template

    def build_attrs(self, attrs, label):
        if label not in attrs:
            return ""
        attr = attrs[label]
        if isinstance(attr, basestring):
            return self.apply_format(attr)
        return u" ".join(map(self.apply_format, attr))

    def as_th(self):
        # TODO get mark_safe to work
        # from django.utils.safestring import mark_safe
        if self.head_attrs and self.label in self.head_attrs:
            return u"<th %s>%s</th>" % (self.build_attrs(self.head_attrs, self.label), self.text)
        return u"<th>%s</th>" % self.text

    def as_td(self):
        if self.body_attrs and self.label in self.body_attrs:
            return u"<td %s>%s</td>" % (self.build_attrs(self.body_attrs, self.label), self.text)
        return u"<td>%s</td>" % self.text

    def as_text(self):
        return self.text

    def __repr__(self):
        return self.as_th()


class ChartBodyCell(ChartCell):
    def __init__(self, obj, fieldname, format=None):
        super(ChartBodyCell, self).__init__(obj, fieldname, format)
        self.raw_text = getattr(obj, fieldname)
        if self.raw_text is None:
            self.text = NULL_DISPLAY
        else:
            self.text = self.format % self.raw_text

    def as_td_data(self):
        return u"<td data-value=\"%s\">%s</td>" % (self.raw_text, self.text)


class SimpleChart(models.Model):
    """ Model mixin that enables quick dumps via a template tag """
    chart_series = []

    chart_excluded_fields = ('id',)

    class Meta:
        abstract = True

    @classmethod
    def get_chart_field_names(cls):
        return [x.name for x in cls._meta.fields if x.name not in cls.chart_excluded_fields]<commit_msg>Make it so we can pass in callables<commit_after>from django.db import models


NULL_DISPLAY = "&ndash;"


class ChartCell(object):
    head_attrs = {}
    body_attrs = {}
    label = ""
    format = "%s"
    text = ""
    raw_text = ""

    def __init__(self, cls, fieldname, format=None):
        self.label = fieldname
        try:
            self.field = cls._meta.get_field(fieldname)
            self.text = self.field.verbose_name
        except models.FieldDoesNotExist:
            try:
                self.text = getattr(cls, fieldname).verbose_name
            except AttributeError:
                self.text = fieldname
        self.raw_text = self.text
        if format is not None:
            self.format = format
        if hasattr(cls, 'chart_head_attrs'):
            self.head_attrs = dict(cls.chart_head_attrs)
        if hasattr(cls, 'chart_body_attrs'):
            self.body_attrs = dict(cls.chart_body_attrs)

    def apply_format(self, template):
        try:
            return template % self.raw_text
        except TypeError:
            return template

    def build_attrs(self, attrs, label):
        if label not in attrs:
            return ""
        attr = attrs[label]
        if isinstance(attr, basestring):
            return self.apply_format(attr)
        return u" ".join(map(self.apply_format, attr))

    def as_th(self):
        # TODO get mark_safe to work
        # from django.utils.safestring import mark_safe
        if self.head_attrs and self.label in self.head_attrs:
            return u"<th %s>%s</th>" % (self.build_attrs(self.head_attrs, self.label), self.text)
        return u"<th>%s</th>" % self.text

    def as_td(self):
        if self.body_attrs and self.label in self.body_attrs:
            return u"<td %s>%s</td>" % (self.build_attrs(self.body_attrs, self.label), self.text)
        return u"<td>%s</td>" % self.text

    def as_text(self):
        return self.text

    def __repr__(self):
        return self.as_th()


class ChartBodyCell(ChartCell):
    def __init__(self, obj, fieldname, format=None):
        super(ChartBodyCell, self).__init__(obj, fieldname, format)
        self.raw_text = getattr(obj, fieldname)
        if hasattr(self.raw_text, '__call__'):
            self.raw_text = self.raw_text()
        if self.raw_text is None:
            self.text = NULL_DISPLAY
        else:
            self.text = self.format % self.raw_text

    def as_td_data(self):
        return u"<td data-value=\"%s\">%s</td>" % (self.raw_text, self.text)


class SimpleChart(models.Model):
    """ Model mixin that enables quick dumps via a template tag """
    chart_series = []

    chart_excluded_fields = ('id',)

    class Meta:
        abstract = True

    @classmethod
    def get_chart_field_names(cls):
        return [x.name for x in cls._meta.fields if x.name not in cls.chart_excluded_fields]
{'fraction_non_alphanumeric': 0.11054729974628488, 'fraction_numerical': 0.0, 'mean_word_length': 2.2851190476190477, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, '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': '4360835', 'n_tokens_mistral': 1734, 'n_tokens_neox': 1725, 'n_words': 411}