<commit_before>from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.utils import timezone
from grandchallenge.core.models import UUIDModel
from grandchallenge.cases.models import Image
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.conf import settings
from guardian.shortcuts import assign_perm

from config.settings import PERMISSION_TYPES


class AbstractAnnotationModel(UUIDModel):
    """
    Abstract model for an annotation linking to a grader.
    Overrides the created attribute from UUIDModel to allow the value to be set to a specific value on save.
    See: https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.DateField.auto_now_add
    """

    grader = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    # Override inherited 'created' attribute to allow setting of value
    created = models.DateTimeField(default=timezone.now)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """ Override save method to enable setting of permissions for retina users """
        created = False
        if self._state.adding:
            created = True

        super(AbstractAnnotationModel, self).save(*args, **kwargs)

        if not created:
            return

        if (
            self.grader.groups.filter(
                name=settings.RETINA_GRADERS_GROUP_NAME
            ).exists()
            or self.grader.groups.filter(
                name=settings.RETINA_ADMINS_GROUP_NAME
            ).exists()
        ):
            model_name = self._meta.model_name
            admins_group = Group.objects.get(
                name=settings.RETINA_ADMINS_GROUP_NAME
            )
            for permission_type in PERMISSION_TYPES:
                permission_name = f"{permission_type}_{model_name}"
                assign_perm(permission_name, self.grader, self)
                assign_perm(permission_name, admins_group, self)


class AbstractSingleAnnotationModel(UUIDModel):
    def save(self, *args, **kwargs):
        """ Override save method to enable setting of permissions for retina users """
        created = False
        if self._state.adding:
            created = True

        super(AbstractSingleAnnotationModel, self).save(*args, **kwargs)

        if not created:
            return

        if (
            self.annotation_set.grader.groups.filter(
                name=settings.RETINA_GRADERS_GROUP_NAME
            ).exists()
            or self.annotation_set.grader.groups.filter(
                name=settings.RETINA_ADMINS_GROUP_NAME
            ).exists()
        ):
            model_name = self._meta.model_name
            admins_group = Group.objects.get(
                name=settings.RETINA_ADMINS_GROUP_NAME
            )
            for permission_type in PERMISSION_TYPES:
                permission_name = f"{permission_type}_{model_name}"
                assign_perm(permission_name, self.annotation_set.grader, self)
                assign_perm(permission_name, admins_group, self)

    class Meta:
        abstract = True


class AbstractImageAnnotationModel(AbstractAnnotationModel):
    """
    Abstract model for annotation linking to a single image
    """

    image = models.ForeignKey(Image, on_delete=models.CASCADE)

    def __str__(self):
        return "<{} by {} on {} for {}>".format(
            self._meta.model_name,
            self.grader.username,
            self.created.strftime("%Y-%m-%d at %H:%M:%S"),
            self.image,
        )

    class Meta:
        abstract = True


class AbstractNamedImageAnnotationModel(AbstractImageAnnotationModel):
    """
    Abstract model for a unique named image annotation.
    Expands upon AbstractImageAnnotationModel and adds a name for the type of annotation
    """

    name = models.CharField(max_length=255)

    class Meta:
        # Create unique together constraint to disallow duplicates
        unique_together = ("image", "grader", "created", "name")
        abstract = True<commit_msg>Fix _meta lookup for non-lowered model name<commit_after>from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.utils import timezone
from grandchallenge.core.models import UUIDModel
from grandchallenge.cases.models import Image
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.conf import settings
from guardian.shortcuts import assign_perm

from config.settings import PERMISSION_TYPES


class AbstractAnnotationModel(UUIDModel):
    """
    Abstract model for an annotation linking to a grader.
    Overrides the created attribute from UUIDModel to allow the value to be set to a specific value on save.
    See: https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.DateField.auto_now_add
    """

    grader = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    # Override inherited 'created' attribute to allow setting of value
    created = models.DateTimeField(default=timezone.now)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """ Override save method to enable setting of permissions for retina users """
        created = False
        if self._state.adding:
            created = True

        super(AbstractAnnotationModel, self).save(*args, **kwargs)

        if not created:
            return

        if (
            self.grader.groups.filter(
                name=settings.RETINA_GRADERS_GROUP_NAME
            ).exists()
            or self.grader.groups.filter(
                name=settings.RETINA_ADMINS_GROUP_NAME
            ).exists()
        ):
            model_name = self._meta.model_name
            admins_group = Group.objects.get(
                name=settings.RETINA_ADMINS_GROUP_NAME
            )
            for permission_type in PERMISSION_TYPES:
                permission_name = f"{permission_type}_{model_name}"
                assign_perm(permission_name, self.grader, self)
                assign_perm(permission_name, admins_group, self)


class AbstractSingleAnnotationModel(UUIDModel):
    def save(self, *args, **kwargs):
        """ Override save method to enable setting of permissions for retina users """
        created = False
        if self._state.adding:
            created = True

        super(AbstractSingleAnnotationModel, self).save(*args, **kwargs)

        if not created:
            return

        if (
            self.annotation_set.grader.groups.filter(
                name=settings.RETINA_GRADERS_GROUP_NAME
            ).exists()
            or self.annotation_set.grader.groups.filter(
                name=settings.RETINA_ADMINS_GROUP_NAME
            ).exists()
        ):
            model_name = self._meta.model_name
            admins_group = Group.objects.get(
                name=settings.RETINA_ADMINS_GROUP_NAME
            )
            for permission_type in PERMISSION_TYPES:
                permission_name = f"{permission_type}_{model_name}"
                assign_perm(permission_name, self.annotation_set.grader, self)
                assign_perm(permission_name, admins_group, self)

    class Meta:
        abstract = True


class AbstractImageAnnotationModel(AbstractAnnotationModel):
    """
    Abstract model for annotation linking to a single image
    """

    image = models.ForeignKey(Image, on_delete=models.CASCADE)

    def __str__(self):
        return "<{} by {} on {} for {}>".format(
            self._meta.object_name,
            self.grader.username,
            self.created.strftime("%Y-%m-%d at %H:%M:%S"),
            self.image,
        )

    class Meta:
        abstract = True


class AbstractNamedImageAnnotationModel(AbstractImageAnnotationModel):
    """
    Abstract model for a unique named image annotation.
    Expands upon AbstractImageAnnotationModel and adds a name for the type of annotation
    """

    name = models.CharField(max_length=255)

    class Meta:
        # Create unique together constraint to disallow duplicates
        unique_together = ("image", "grader", "created", "name")
        abstract = True
{'fraction_non_alphanumeric': 0.0805017659237608, 'fraction_numerical': 0.001217878455730118, 'mean_word_length': 2.4620573355817874, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, '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': '1354734', 'n_tokens_mistral': 2243, 'n_tokens_neox': 2134, 'n_words': 551}