<commit_before>from __future__ import absolute_import, unicode_literals

from dash.orgs.models import Org
from dash.utils import intersection
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.db import models
from django.db.models import Q, Count, Prefetch
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from enum import Enum, IntEnum
from itertools import chain
from django_redis import get_redis_connection

from casepro.backend import get_backend
from casepro.contacts.models import Contact
from casepro.msgs.models import Label, Message, Outgoing
from casepro.utils import TimelineItem
from casepro.utils.export import BaseSearchExport


CASE_LOCK_KEY = 'org:%d:case_lock:%s'


class CaseFolder(Enum):
    open = 1
    closed = 2


class AccessLevel(IntEnum):
    """
    Case access level
    """
    none = 0
    read = 1
    update = 2


@python_2_unicode_compatible
class Partner(models.Model):
    """
    Corresponds to a partner organization
    """
    org = models.ForeignKey(Org, verbose_name=_("Organization"), related_name='partners')

    name = models.CharField(verbose_name=_("Name"), max_length=128,
                            help_text=_("Name of this partner organization"))

    is_restricted = models.BooleanField(default=True, verbose_name=_("Restricted Access"),
                                        help_text=_("Whether this partner's access is restricted by labels"))

    labels = models.ManyToManyField(Label, verbose_name=_("Labels"), related_name='partners',
                                    help_text=_("Labels that this partner can access"))

    logo = models.ImageField(verbose_name=_("Logo"), upload_to='partner_logos', null=True, blank=True)

    is_active = models.BooleanField(default=True, help_text="Whether this partner is active")

    @classmethod
    def create(cls, org, name, restricted, labels, logo=None):
        if labels and not restricted:
            raise ValueError("Can't specify labels for a partner which is not restricted")

        partner = cls.objects.create(org=org, name=name, logo=logo, is_restricted=restricted)

        if restricted:
            partner.labels.add(*labels)

        return partner

    @classmethod
    def get_all(cls, org):
        return cls.objects.filter(org=org, is_active=True)

    def get_labels(self):
        return self.labels.filter(is_active=True) if self.is_restricted else Label.get_all(self.org)

    def get_users(self):
        return User.objects.filter(profile__partner=self, is_active=True)

    def get_managers(self):
        return self.get_users().filter(org_editors=self.org_id)

    def get_analysts(self):
        return self.get_users().filter(org_viewers=self.org_id)

    def release(self):
        # detach all users
        self.user_profiles.update(partner=None)

        self.is_active = False
        self.save(update_fields=('is_active',))

    def as_json(self, full=True):
        result = {'id': self.pk, 'name': self.name}

        if full:
            result['restricted'] = self.is_restricted

        return result

    def __str__(self):
        return self.name


class case_action(object):
    """
    Helper decorator for case action methods that should check the user is allowed to update the case
    """
    def __init__(self, require_update=True, become_watcher=False):
        self.require_update = require_update
        self.become_watcher = become_watcher

    def __call__(self, func):
        def wrapped(case, user, *args, **kwargs):
            access = case.access_level(user)
            if (access == AccessLevel.update) or (not self.require_update and access == AccessLevel.read):
                result = func(case, user, *args, **kwargs)

                if self.become_watcher:
                    case.watchers.add(user)

                return result
            else:
                raise PermissionDenied()
        return wrapped


@python_2_unicode_compatible
class Case(models.Model):
    """
    A case between a partner organization and a contact
    """
    org = models.ForeignKey(Org, verbose_name=_("Organization"), related_name='cases')

    labels = models.ManyToManyField(Label, help_text=_("Labels assigned to this case"))

    assignee = models.ForeignKey(Partner, related_name='cases')

    contact = models.ForeignKey(Contact, related_name='cases')

    initial_message = models.OneToOneField(Message, related_name='initial_case')

    summary = models.CharField(verbose_name=_("Summary"), max_length=255)

    opened_on = models.DateTimeField(auto_now_add=True,
                                     help_text="When this case was opened")

    closed_on = models.DateTimeField(null=True,
                                     help_text="When this case was closed")

    watchers = models.ManyToManyField(User, related_name='watched_cases',
                                      help_text="Users to be notified of case activity")

    @classmethod
    def get_all(cls, org, user=None, label=None):<commit_msg>Add user_assignee field for assigning a user to a case<commit_after>from __future__ import absolute_import, unicode_literals

from dash.orgs.models import Org
from dash.utils import intersection
from django.contrib.auth.models import User
from django.core.exceptions import PermissionDenied
from django.db import models
from django.db.models import Q, Count, Prefetch
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from enum import Enum, IntEnum
from itertools import chain
from django_redis import get_redis_connection

from casepro.backend import get_backend
from casepro.contacts.models import Contact
from casepro.msgs.models import Label, Message, Outgoing
from casepro.utils import TimelineItem
from casepro.utils.export import BaseSearchExport


CASE_LOCK_KEY = 'org:%d:case_lock:%s'


class CaseFolder(Enum):
    open = 1
    closed = 2


class AccessLevel(IntEnum):
    """
    Case access level
    """
    none = 0
    read = 1
    update = 2


@python_2_unicode_compatible
class Partner(models.Model):
    """
    Corresponds to a partner organization
    """
    org = models.ForeignKey(Org, verbose_name=_("Organization"), related_name='partners')

    name = models.CharField(verbose_name=_("Name"), max_length=128,
                            help_text=_("Name of this partner organization"))

    is_restricted = models.BooleanField(default=True, verbose_name=_("Restricted Access"),
                                        help_text=_("Whether this partner's access is restricted by labels"))

    labels = models.ManyToManyField(Label, verbose_name=_("Labels"), related_name='partners',
                                    help_text=_("Labels that this partner can access"))

    logo = models.ImageField(verbose_name=_("Logo"), upload_to='partner_logos', null=True, blank=True)

    is_active = models.BooleanField(default=True, help_text="Whether this partner is active")

    @classmethod
    def create(cls, org, name, restricted, labels, logo=None):
        if labels and not restricted:
            raise ValueError("Can't specify labels for a partner which is not restricted")

        partner = cls.objects.create(org=org, name=name, logo=logo, is_restricted=restricted)

        if restricted:
            partner.labels.add(*labels)

        return partner

    @classmethod
    def get_all(cls, org):
        return cls.objects.filter(org=org, is_active=True)

    def get_labels(self):
        return self.labels.filter(is_active=True) if self.is_restricted else Label.get_all(self.org)

    def get_users(self):
        return User.objects.filter(profile__partner=self, is_active=True)

    def get_managers(self):
        return self.get_users().filter(org_editors=self.org_id)

    def get_analysts(self):
        return self.get_users().filter(org_viewers=self.org_id)

    def release(self):
        # detach all users
        self.user_profiles.update(partner=None)

        self.is_active = False
        self.save(update_fields=('is_active',))

    def as_json(self, full=True):
        result = {'id': self.pk, 'name': self.name}

        if full:
            result['restricted'] = self.is_restricted

        return result

    def __str__(self):
        return self.name


class case_action(object):
    """
    Helper decorator for case action methods that should check the user is allowed to update the case
    """
    def __init__(self, require_update=True, become_watcher=False):
        self.require_update = require_update
        self.become_watcher = become_watcher

    def __call__(self, func):
        def wrapped(case, user, *args, **kwargs):
            access = case.access_level(user)
            if (access == AccessLevel.update) or (not self.require_update and access == AccessLevel.read):
                result = func(case, user, *args, **kwargs)

                if self.become_watcher:
                    case.watchers.add(user)

                return result
            else:
                raise PermissionDenied()
        return wrapped


@python_2_unicode_compatible
class Case(models.Model):
    """
    A case between a partner organization and a contact
    """
    org = models.ForeignKey(Org, verbose_name=_("Organization"), related_name='cases')

    labels = models.ManyToManyField(Label, help_text=_("Labels assigned to this case"))

    assignee = models.ForeignKey(Partner, related_name='cases')

    user_assignee = models.ForeignKey(
        User, null=True, on_delete=models.SET_NULL, related_name='cases',
        help_text="The (optional) user that this case is assigned to")

    contact = models.ForeignKey(Contact, related_name='cases')

    initial_message = models.OneToOneField(Message, related_name='initial_case')

    summary = models.CharField(verbose_name=_("Summary"), max_length=255)

    opened_on = models.DateTimeField(auto_now_add=True,
                                     help_text="When this case was opened")

    closed_on = models.DateTimeField(null=True,
                                     help_text="When this case was closed")

    watchers = models.ManyToManyField(User, related_name='watched_cases',
                                      help_text="Users to be notified of case activity")

    @classmethod
    def get_all(cls, org, user=None, label=None):
{'fraction_non_alphanumeric': 0.09319441789332823, 'fraction_numerical': 0.0026763525138596826, 'mean_word_length': 3.0951076320939332, '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': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '625223', 'n_tokens_mistral': 3027, 'n_tokens_neox': 2874, 'n_words': 749}