<commit_before>from datetime import timedelta

from celery.task import control as celery_control
from django.core.urlresolvers import reverse
from django.core.validators import MaxLengthValidator, MinLengthValidator
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models, transaction
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from django.utils.timezone import now

from django_statsd.clients import statsd
from south.signals import post_migrate
from uuslug import uuslug

from remo.base.tasks import send_remo_mail
from remo.base.utils import add_permissions_to_groups
from remo.dashboard.models import ActionItem, Item
from remo.remozilla.models import Bug
from remo.remozilla.utils import get_bugzilla_url
from remo.voting.tasks import send_voting_mail


# Voting period in days
BUDGET_REQUEST_PERIOD_START = 3
BUDGET_REQUEST_PERIOD_END = 6
VOTE_ACTION = 'Cast your vote for'
BUDGET_VOTE_ACTION = 'Cast your vote for budget request'


class Poll(models.Model):
    """Poll Model."""
    name = models.CharField(max_length=300)
    slug = models.SlugField(blank=True, max_length=255)
    start = models.DateTimeField()
    end = models.DateTimeField()
    valid_groups = models.ForeignKey(Group, related_name='valid_polls')
    created_on = models.DateTimeField(auto_now_add=True)
    description = models.TextField(validators=[MaxLengthValidator(1500),
                                               MinLengthValidator(20)])
    created_by = models.ForeignKey(User, related_name='range_polls_created')
    users_voted = models.ManyToManyField(User, related_name='polls_voted',
                                         through='Vote')
    task_start_id = models.CharField(max_length=256, blank=True,
                                     null=True, editable=False, default='')
    task_end_id = models.CharField(max_length=256, blank=True, null=True,
                                   editable=False, default='')
    bug = models.ForeignKey(Bug, null=True, blank=True)
    automated_poll = models.BooleanField(default=False)
    comments_allowed = models.BooleanField(default=True)
    is_extended = models.BooleanField(default=False)
    action_items = generic.GenericRelation(ActionItem)

    def get_absolute_url(self):
        return reverse('remo.voting.views.view_voting',
                       args=[self.slug])

    @property
    def is_future_voting(self):
        if self.start > now():
            return True
        return False

    @property
    def is_current_voting(self):
        if self.start < now() and self.end > now():
            return True
        return False

    @property
    def is_past_voting(self):
        if self.end < now():
            return True
        return False

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['-created_on']

    def save(self, *args, **kwargs):
        if not self.pk:
            self.slug = uuslug(self.name, instance=self)
        else:
            # Update action items
            current_poll = Poll.objects.get(id=self.pk)
            action_model = ContentType.objects.get_for_model(self)
            action_items = ActionItem.objects.filter(content_type=action_model,
                                                     object_id=self.pk)

            if current_poll.end != self.end:
                action_items.update(due_date=self.end.date())

            if current_poll.valid_groups != self.valid_groups:
                action_items.delete()
                ActionItem.create(self)

            if not settings.CELERY_ALWAYS_EAGER:
                if self.is_current_voting:
                    celery_control.revoke(self.task_end_id)
                elif self.is_future_voting:
                    celery_control.revoke(self.task_start_id)
                    celery_control.revoke(self.task_end_id)

            if not self.is_future_voting:
                obj = Poll.objects.get(pk=self.id)
                if self.end > obj.end:
                    self.is_extended = True

        super(Poll, self).save()

    def get_action_items(self):
        action_items = []
        due_date = self.end.date()

        if self.automated_poll:
            name = '{0} {1}'.format(BUDGET_VOTE_ACTION, self.bug.summary)
            priority = ActionItem.MAJOR
        else:
            name = '{0} {1}'.format(VOTE_ACTION, self.name)
            priority = ActionItem.NORMAL

        for user in User.objects.filter(groups=self.valid_groups):
            action_item = Item(name, user, priority, due_date)
            action_items.append(action_item)

        return action_items


class Vote(models.Model):
    """Vote model."""
    user = models.ForeignKey(User)
    poll = models.ForeignKey(Poll)
    date_voted = models.DateField(auto_now_add=True)

    def __unicode__(self):
        return '%s %s' % (self.user, self.poll)

    def save(self, *args, **kwargs):
        if self.poll.automated_poll:
            name = '{0} {1}'.format(BUDGET_VOTE_ACTION, self.poll.bug.summary)
        else:
            name = '{0} {1}'.format(VOTE_ACTION, self.poll.name)

        super(Vote, self).save(*args, **kwargs)
        ActionItem.resolve(instance=self.poll, user=self.user,
                           name=name)


class RangePoll(models.Model):
    """Range Poll Model."""
    name = models.CharField(max_length=500, default='')
    poll = models.ForeignKey(Poll, related_name='range_polls')

    def __unicode__(self):
        return self.name


class RangePollChoice(models.Model):
    """Range Poll Choice Model."""
    votes = models.IntegerField(default=0)
    range_poll = models.ForeignKey(RangePoll, related_name='choices')
    nominee = models.ForeignKey(User, limit_choices_to={'groups__name': 'Rep'})

    class Meta:
        ordering = ['-votes', 'nominee__last_name', 'nominee__first_name']


class RadioPoll(models.Model):
    """Radio Poll Model."""
    question = models.CharField(max_length=500)
    poll = models.ForeignKey(Poll, related_name='radio_polls')<commit_msg>[fix bug 1138370] Fix unicode error when creating action items.<commit_after>from datetime import timedelta

from celery.task import control as celery_control
from django.core.urlresolvers import reverse
from django.core.validators import MaxLengthValidator, MinLengthValidator
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models, transaction
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from django.utils.timezone import now

from django_statsd.clients import statsd
from south.signals import post_migrate
from uuslug import uuslug

from remo.base.tasks import send_remo_mail
from remo.base.utils import add_permissions_to_groups
from remo.dashboard.models import ActionItem, Item
from remo.remozilla.models import Bug
from remo.remozilla.utils import get_bugzilla_url
from remo.voting.tasks import send_voting_mail


# Voting period in days
BUDGET_REQUEST_PERIOD_START = 3
BUDGET_REQUEST_PERIOD_END = 6
VOTE_ACTION = 'Cast your vote for'
BUDGET_VOTE_ACTION = 'Cast your vote for budget request'


class Poll(models.Model):
    """Poll Model."""
    name = models.CharField(max_length=300)
    slug = models.SlugField(blank=True, max_length=255)
    start = models.DateTimeField()
    end = models.DateTimeField()
    valid_groups = models.ForeignKey(Group, related_name='valid_polls')
    created_on = models.DateTimeField(auto_now_add=True)
    description = models.TextField(validators=[MaxLengthValidator(1500),
                                               MinLengthValidator(20)])
    created_by = models.ForeignKey(User, related_name='range_polls_created')
    users_voted = models.ManyToManyField(User, related_name='polls_voted',
                                         through='Vote')
    task_start_id = models.CharField(max_length=256, blank=True,
                                     null=True, editable=False, default='')
    task_end_id = models.CharField(max_length=256, blank=True, null=True,
                                   editable=False, default='')
    bug = models.ForeignKey(Bug, null=True, blank=True)
    automated_poll = models.BooleanField(default=False)
    comments_allowed = models.BooleanField(default=True)
    is_extended = models.BooleanField(default=False)
    action_items = generic.GenericRelation(ActionItem)

    def get_absolute_url(self):
        return reverse('remo.voting.views.view_voting',
                       args=[self.slug])

    @property
    def is_future_voting(self):
        if self.start > now():
            return True
        return False

    @property
    def is_current_voting(self):
        if self.start < now() and self.end > now():
            return True
        return False

    @property
    def is_past_voting(self):
        if self.end < now():
            return True
        return False

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['-created_on']

    def save(self, *args, **kwargs):
        if not self.pk:
            self.slug = uuslug(self.name, instance=self)
        else:
            # Update action items
            current_poll = Poll.objects.get(id=self.pk)
            action_model = ContentType.objects.get_for_model(self)
            action_items = ActionItem.objects.filter(content_type=action_model,
                                                     object_id=self.pk)

            if current_poll.end != self.end:
                action_items.update(due_date=self.end.date())

            if current_poll.valid_groups != self.valid_groups:
                action_items.delete()
                ActionItem.create(self)

            if not settings.CELERY_ALWAYS_EAGER:
                if self.is_current_voting:
                    celery_control.revoke(self.task_end_id)
                elif self.is_future_voting:
                    celery_control.revoke(self.task_start_id)
                    celery_control.revoke(self.task_end_id)

            if not self.is_future_voting:
                obj = Poll.objects.get(pk=self.id)
                if self.end > obj.end:
                    self.is_extended = True

        super(Poll, self).save()

    def get_action_items(self):
        action_items = []
        due_date = self.end.date()

        if self.automated_poll:
            name = '{0} {1}'.format(BUDGET_VOTE_ACTION, self.bug.summary)
            priority = ActionItem.MAJOR
        else:
            name = '{0} {1}'.format(VOTE_ACTION, self.name)
            priority = ActionItem.NORMAL

        for user in User.objects.filter(groups=self.valid_groups):
            action_item = Item(name, user, priority, due_date)
            action_items.append(action_item)

        return action_items


class Vote(models.Model):
    """Vote model."""
    user = models.ForeignKey(User)
    poll = models.ForeignKey(Poll)
    date_voted = models.DateField(auto_now_add=True)

    def __unicode__(self):
        return u'{0} {1}'.format(self.user, self.poll)

    def save(self, *args, **kwargs):
        if self.poll.automated_poll:
            name = u'{0} {1}'.format(BUDGET_VOTE_ACTION, self.poll.bug.summary)
        else:
            name = u'{0} {1}'.format(VOTE_ACTION, self.poll.name)

        super(Vote, self).save(*args, **kwargs)
        ActionItem.resolve(instance=self.poll, user=self.user,
                           name=name)


class RangePoll(models.Model):
    """Range Poll Model."""
    name = models.CharField(max_length=500, default='')
    poll = models.ForeignKey(Poll, related_name='range_polls')

    def __unicode__(self):
        return self.name


class RangePollChoice(models.Model):
    """Range Poll Choice Model."""
    votes = models.IntegerField(default=0)
    range_poll = models.ForeignKey(RangePoll, related_name='choices')
    nominee = models.ForeignKey(User, limit_choices_to={'groups__name': 'Rep'})

    class Meta:
        ordering = ['-votes', 'nominee__last_name', 'nominee__first_name']


class RadioPoll(models.Model):
    """Radio Poll Model."""
    question = models.CharField(max_length=500)
    poll = models.ForeignKey(Poll, related_name='radio_polls')
{'fraction_non_alphanumeric': 0.09733663920659041, 'fraction_numerical': 0.006318483563944653, 'mean_word_length': 2.671168526130358, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6305405', 'n_tokens_mistral': 3794, 'n_tokens_neox': 3640, 'n_words': 761}