<commit_before>import importlib
import datetime
import math

from dateutil.relativedelta import relativedelta

from kardboard.app import app

from mongoengine.queryset import Q
from flask.ext.mongoengine import QuerySet

from kardboard.models.blocker import BlockerRecord
from kardboard.models.states import States
from kardboard.util import (
    now,
    business_days_between,
    make_end_date,
    make_start_date,
    munge_date,
    month_range,
    week_range,
)

class KardQuerySet(QuerySet):
    def done_in_week(self, year=None, month=None, day=None, date=None):
        """
        Kards that were completed in the week of the specified day.
        """
        if not date:
            date = munge_date(year, month, day)
            date = make_end_date(date=date)
        start_date, end_date = week_range(date)

        results = self.done().filter(
            done_date__lte=date,
            done_date__gte=start_date
        )
        return results

    def average(self, field_str):
        count = self.count()
        the_sum = sum([getattr(k, field_str) for k in self.filter().only(field_str)])

        if count == 0:
            return float('nan')

        return the_sum / float(count)

    def moving_cycle_time(self, year=None, month=None, day=None, weeks=4):
        """
        The moving average of cycle time for every day in the last N weeks.
        """

        end_date = make_end_date(year, month, day)
        start_date = end_date - relativedelta(weeks=weeks)
        start_date = make_start_date(date=start_date)

        qs = self.done().filter(
            done_date__lte=end_date,
            done_date__gte=start_date,
            )

        try:
            average = qs.average('_cycle_time')
        except TypeError:
            average = float('nan')

        if math.isnan(average):
            return 0

        return int(round(average))

    def moving_lead_time(self, year=None, month=None, day=None, weeks=4):
        """
        The moving average of lead time for every day in the last N weeks.
        """

        end_date = make_end_date(year, month, day)
        start_date = end_date - relativedelta(weeks=weeks)
        start_date = make_start_date(date=start_date)

        qs = self.done().filter(
            done_date__lte=end_date,
            done_date__gte=start_date,
            )

        average = qs.average('_lead_time')
        if math.isnan(average):
            average = 0

        return int(round(average))

    def done(self):
        """
        Kards that have been completed.
        """
        return self.filter(done_date__exists=True)

    def done_in_month(self, year=None, month=None, day=None, date=None):
        """
        Kards that have been completed in the specified month.
        """
        if not date:
            date = munge_date(year=year, month=month, day=day)
            date = make_end_date(date=date)

        start_date, faux_end_date = month_range(date)

        results = self.done().filter(done_date__lte=date,
            done_date__gte=start_date)
        return results

class Kard(app.db.Document):
    """
    Represents a card on a Kanban board.
    """
    _ticket_system = None

    key = app.db.StringField(required=True, unique=True)
    """A unique string that matches a Kard up to a ticket in a parent system."""

    title = app.db.StringField()
    backlog_date = app.db.DateTimeField(required=True)
    """When the card entered the backlog."""

    start_date = app.db.DateTimeField()
    """When the card was started."""

    done_date = app.db.DateTimeField()
    """When the card was completed."""

    _cycle_time = app.db.IntField(db_field="cycle_time")
    _lead_time = app.db.IntField(db_field="lead_time")
    team = app.db.StringField(required=True, default="")
    """A selection from a user supplied list of teams/assignees. See :ref:`CARD_TEAMS`"""

    state = app.db.StringField(required=True, default="Unknown")
    """Which column on the kanban board the card is in."""
    priority = app.db.IntField(required=False)
    """Used when ordering cards in the backlog."""

    blocked = app.db.BooleanField(default=False)
    """Is the card currently blocked."""

    blocked_ever = app.db.BooleanField(default=False)
    """Was the card ever blocked in its history."""

    blockers = app.db.ListField(
        app.db.EmbeddedDocumentField(BlockerRecord),
    )

    created_at = app.db.DateTimeField(required=True)

    _service_class = app.db.StringField(required=True, db_field="service_class")
    _assignee = app.db.StringField(db_field="assignee")
    _version = app.db.StringField(required=False, db_field="version")

    _ticket_system_updated_at = app.db.DateTimeField()
    _ticket_system_data = app.db.DictField()

    meta = {
        'queryset_class': KardQuerySet,
        'collection': 'kard',
        'ordering': ['+priority', '-backlog_date'],
        'indexes': [('state', 'team'), ('team', 'done_date')],
    }

    EXPORT_FIELDNAMES = (
        'key',
        'title',
        'backlog_date',
        'start_date',
        'done_date',
        'state',
    )

    def _convert_dates_to_datetimes(self, date):
        if not date:<commit_msg>Working around bug in mongoengine to fix #112<commit_after>import importlib
import datetime
import math

from dateutil.relativedelta import relativedelta

from kardboard.app import app

from mongoengine.queryset import Q
from flask.ext.mongoengine import QuerySet

from kardboard.models.blocker import BlockerRecord
from kardboard.models.states import States
from kardboard.util import (
    now,
    business_days_between,
    make_end_date,
    make_start_date,
    munge_date,
    month_range,
    week_range,
)

class KardQuerySet(QuerySet):
    def done_in_week(self, year=None, month=None, day=None, date=None):
        """
        Kards that were completed in the week of the specified day.
        """
        if not date:
            date = munge_date(year, month, day)
            date = make_end_date(date=date)
        start_date, end_date = week_range(date)

        results = self.done().filter(
            done_date__lte=date,
            done_date__gte=start_date
        )
        return results

    def average(self, field_str):
        count = self.count()
        the_sum = sum([getattr(k, field_str) for k in self.filter().only(field_str)])

        if count == 0:
            return float('nan')

        return the_sum / float(count)

    def distinct(self, field_str):
        if field_str == "_service_class":
            field_str = "service_class"
            return self._cursor.distinct(field_str)
        return super(KardQuerySet, self).distinct(field_str)

    def moving_cycle_time(self, year=None, month=None, day=None, weeks=4):
        """
        The moving average of cycle time for every day in the last N weeks.
        """

        end_date = make_end_date(year, month, day)
        start_date = end_date - relativedelta(weeks=weeks)
        start_date = make_start_date(date=start_date)

        qs = self.done().filter(
            done_date__lte=end_date,
            done_date__gte=start_date,
            )

        try:
            average = qs.average('_cycle_time')
        except TypeError:
            average = float('nan')

        if math.isnan(average):
            return 0

        return int(round(average))

    def moving_lead_time(self, year=None, month=None, day=None, weeks=4):
        """
        The moving average of lead time for every day in the last N weeks.
        """

        end_date = make_end_date(year, month, day)
        start_date = end_date - relativedelta(weeks=weeks)
        start_date = make_start_date(date=start_date)

        qs = self.done().filter(
            done_date__lte=end_date,
            done_date__gte=start_date,
            )

        average = qs.average('_lead_time')
        if math.isnan(average):
            average = 0

        return int(round(average))

    def done(self):
        """
        Kards that have been completed.
        """
        return self.filter(done_date__exists=True)

    def done_in_month(self, year=None, month=None, day=None, date=None):
        """
        Kards that have been completed in the specified month.
        """
        if not date:
            date = munge_date(year=year, month=month, day=day)
            date = make_end_date(date=date)

        start_date, faux_end_date = month_range(date)

        results = self.done().filter(done_date__lte=date,
            done_date__gte=start_date)
        return results

class Kard(app.db.Document):
    """
    Represents a card on a Kanban board.
    """
    _ticket_system = None

    key = app.db.StringField(required=True, unique=True)
    """A unique string that matches a Kard up to a ticket in a parent system."""

    title = app.db.StringField()
    backlog_date = app.db.DateTimeField(required=True)
    """When the card entered the backlog."""

    start_date = app.db.DateTimeField()
    """When the card was started."""

    done_date = app.db.DateTimeField()
    """When the card was completed."""

    _cycle_time = app.db.IntField(db_field="cycle_time")
    _lead_time = app.db.IntField(db_field="lead_time")
    team = app.db.StringField(required=True, default="")
    """A selection from a user supplied list of teams/assignees. See :ref:`CARD_TEAMS`"""

    state = app.db.StringField(required=True, default="Unknown")
    """Which column on the kanban board the card is in."""
    priority = app.db.IntField(required=False)
    """Used when ordering cards in the backlog."""

    blocked = app.db.BooleanField(default=False)
    """Is the card currently blocked."""

    blocked_ever = app.db.BooleanField(default=False)
    """Was the card ever blocked in its history."""

    blockers = app.db.ListField(
        app.db.EmbeddedDocumentField(BlockerRecord),
    )

    created_at = app.db.DateTimeField(required=True)

    _service_class = app.db.StringField(required=True, db_field="service_class")
    _assignee = app.db.StringField(db_field="assignee")
    _version = app.db.StringField(required=False, db_field="version")

    _ticket_system_updated_at = app.db.DateTimeField()
    _ticket_system_data = app.db.DictField()

    meta = {
        'queryset_class': KardQuerySet,
        'collection': 'kard',
        'ordering': ['+priority', '-backlog_date'],
        'auto_create_index': True,
        'indexes': [('state', 'team'), ('team', 'done_date'), '_service_class', '_cycle_time', '_lead_time'],
    }

    EXPORT_FIELDNAMES = (
        'key',
        'title',
        'backlog_date',
        'start_date',
        'done_date',
        'state',
    )

    def _convert_dates_to_datetimes(self, date):
        if not date:
{'fraction_non_alphanumeric': 0.10944903837220106, 'fraction_numerical': 0.001207841679829044, 'mean_word_length': 2.624242424242424, 'pattern_counts': {'":': 1, '<': 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': '4193208', 'n_tokens_mistral': 3400, 'n_tokens_neox': 3286, 'n_words': 780}