<commit_before>import os
import re
from datetime import datetime

from django.contrib.auth.models import User
from django.db import models
from django.db.models import Q, permalink

from djblets.util.misc import get_object_or_none
from djblets.util.db import QLeftOuterJoins

from reviewboard.diffviewer.models import DiffSet, DiffSetHistory, FileDiff
from reviewboard.scmtools.models import Repository
from reviewboard.utils.fields import ModificationTimestampField
from utils.templatetags.htmlutils import crop_image, thumbnail


class InvalidChangeNumberError(Exception):
    def __init__(self):
        Exception.__init__(self, None)


class ChangeNumberInUseError(Exception):
    def __init__(self, review_request=None):
        Exception.__init__(self, None)
        self.review_request = review_request


class Group(models.Model):
    name = models.SlugField(maxlength=64)
    display_name = models.CharField(maxlength=64)
    mailing_list = models.EmailField(blank=True)
    users = models.ManyToManyField(User, core=False, blank=True,
                                   filter_interface=models.HORIZONTAL)

    def __unicode__(self):
        return self.name

    @permalink
    def get_absolute_url(self):
        return ('reviewboard.reviews.views.group', None, {'name': self.name})

    class Admin:
        list_display = ('name', 'display_name', 'mailing_list')

    class Meta:
        verbose_name = "review group"
        ordering = ['name']


class Screenshot(models.Model):
    caption = models.CharField(maxlength=256, blank=True)
    draft_caption = models.CharField(maxlength=256, blank=True)
    image = models.ImageField(upload_to=os.path.join('images', 'uploaded'))

    def thumb(self):
        url = thumbnail(self.image)
        return '<img src="%s" alt="%s" />' % (url, self.caption)
    thumb.allow_tags = True

    def __unicode__(self):
        return "%s (%s)" % (self.caption, self.image)

    @permalink
    def get_absolute_url(self):
        try:
            review = self.review_request.all()[0]
        except IndexError:
            review = self.inactive_review_request.all()[0]

        return ('reviewboard.reviews.views.view_screenshot', None, {
            'review_request_id': review.id,
            'screenshot_id': self.id
        })

    class Admin:
        list_display = ('thumb', 'caption', 'image')
        list_display_links = ('thumb', 'caption')


class ReviewRequestManager(models.Manager):
    """
    A manager for review requests. Provides specialized queries to retrieve
    review requests with specific targets or origins, and to create review
    requests based on certain data.
    """

    def create(self, user, repository, changenum=None):
        """
        Creates a new review request, optionally filling in fields based off
        a change number.
        """
        if changenum:
            try:
                review_request = self.get(changenum=changenum,
                                          repository=repository)
                raise ChangeNumberInUseError(review_request)
            except ReviewRequest.DoesNotExist:
                pass

        review_request = ReviewRequest(repository=repository)

        if changenum:
            review_request.update_from_changenum(changenum)

        diffset_history = DiffSetHistory()
        diffset_history.save()

        review_request.diffset_history = diffset_history
        review_request.submitter = user
        review_request.status = 'P'
        review_request.public = False
        review_request.save()

        return review_request

    def public(self, user=None, status='P'):
        return self._query(user, status)

    def to_group(self, group_name, user=None, status='P'):
        return self._query(user, status, Q(target_groups__name=group_name))

    def to_user_groups(self, username, user=None, status='P'):
        return self._query(user, status,
                           Q(target_groups__users__username=username))

    def to_user_directly(self, username, user=None, status='P'):
        query = QLeftOuterJoins(Q(target_people__username=username) |
                                Q(starred_by__user__username=username))
        return self._query(user, status, query)

    def to_user(self, username, user=None, status='P'):
        query = QLeftOuterJoins(Q(target_groups__users__username=username) |
                                Q(target_people__username=username) |
                                Q(starred_by__user__username=username))
        return self._query(user, status, query)

    def from_user(self, username, user=None, status='P'):
        return self._query(user, status, Q(submitter__username=username))

    def _query(self, user, status, extra_query=None):
        query = Q(public=True)

        if user and user.is_authenticated():
            query = query | Q(submitter=user)

        if status:
            query = query & Q(status=status)

        if extra_query:
            query = query & extra_query

        return self.filter(query).distinct()


class ReviewRequest(models.Model):
    STATUSES = (
        ('P', 'Pending Review'),
        ('S', 'Submitted'),
        ('D', 'Discarded'),
    )

    submitter = models.ForeignKey(User, verbose_name="Submitter")
    time_added = models.DateTimeField("Time Added", default=datetime.now)
    last_updated = ModificationTimestampField("Last Updated")
    status = models.CharField(maxlength=1, choices=STATUSES)
    public = models.BooleanField("Public", default=False)
    changenum = models.PositiveIntegerField("Change Number", blank=True,
                                            null=True, db_index=True)
    repository = models.ForeignKey(Repository)
    email_message_id = models.CharField("E-Mail Message ID", maxlength=255,
                                        blank=True, null=True)
    time_emailed = models.DateTimeField("Time E-Mailed", null=True,
                                        default=None, blank=True)

    summary = models.CharField("Summary", maxlength=300, core=True)
    description = models.TextField("Description", blank=True)
    testing_done = models.TextField("Testing Done", blank=True)
    bugs_closed = models.CommaSeparatedIntegerField("Bugs",
                                                    maxlength=300, blank=True)
    diffset_history = models.ForeignKey(DiffSetHistory,
                                        verbose_name='diff set history',
                                        blank=True)
    branch = models.CharField("Branch", maxlength=300, blank=True)
    target_groups = models.ManyToManyField(Group, verbose_name="Target Groups",
                                           core=False, blank=True)
    target_people = models.ManyToManyField(User, verbose_name="Target People",
                                           related_name="directed_review_requests",
                                           core=False, blank=True)
    screenshots = models.ManyToManyField(Screenshot, verbose_name="Screenshots",
                                         related_name="review_request",
                                         core=False, blank=True)
    inactive_screenshots = models.ManyToManyField(Screenshot,
        related_name="inactive_review_request", core=False, blank=True)


    # Set this up with the ReviewRequestManager
    objects = ReviewRequestManager()


    def get_bug_list(self):
        bugs = re.split(r"[, ]+", self.bugs_closed)
        bugs.sort(cmp=lambda x,y: int(x) - int(y))
        return bugs

    def get_new_reviews(self, user):
        """
        Returns any new reviews since the user last viewed the review request.
        """
        if user.is_authenticated():
            visit = get_object_or_none(self.visits, user=user)<commit_msg>Added filter interfaces for screenshots and target reviewers on the review request admin page.<commit_after>import os
import re
from datetime import datetime

from django.contrib.auth.models import User
from django.db import models
from django.db.models import Q, permalink

from djblets.util.misc import get_object_or_none
from djblets.util.db import QLeftOuterJoins

from reviewboard.diffviewer.models import DiffSet, DiffSetHistory, FileDiff
from reviewboard.scmtools.models import Repository
from reviewboard.utils.fields import ModificationTimestampField
from utils.templatetags.htmlutils import crop_image, thumbnail


class InvalidChangeNumberError(Exception):
    def __init__(self):
        Exception.__init__(self, None)


class ChangeNumberInUseError(Exception):
    def __init__(self, review_request=None):
        Exception.__init__(self, None)
        self.review_request = review_request


class Group(models.Model):
    name = models.SlugField(maxlength=64)
    display_name = models.CharField(maxlength=64)
    mailing_list = models.EmailField(blank=True)
    users = models.ManyToManyField(User, core=False, blank=True,
                                   filter_interface=models.HORIZONTAL)

    def __unicode__(self):
        return self.name

    @permalink
    def get_absolute_url(self):
        return ('reviewboard.reviews.views.group', None, {'name': self.name})

    class Admin:
        list_display = ('name', 'display_name', 'mailing_list')

    class Meta:
        verbose_name = "review group"
        ordering = ['name']


class Screenshot(models.Model):
    caption = models.CharField(maxlength=256, blank=True)
    draft_caption = models.CharField(maxlength=256, blank=True)
    image = models.ImageField(upload_to=os.path.join('images', 'uploaded'))

    def thumb(self):
        url = thumbnail(self.image)
        return '<img src="%s" alt="%s" />' % (url, self.caption)
    thumb.allow_tags = True

    def __unicode__(self):
        return "%s (%s)" % (self.caption, self.image)

    @permalink
    def get_absolute_url(self):
        try:
            review = self.review_request.all()[0]
        except IndexError:
            review = self.inactive_review_request.all()[0]

        return ('reviewboard.reviews.views.view_screenshot', None, {
            'review_request_id': review.id,
            'screenshot_id': self.id
        })

    class Admin:
        list_display = ('thumb', 'caption', 'image')
        list_display_links = ('thumb', 'caption')


class ReviewRequestManager(models.Manager):
    """
    A manager for review requests. Provides specialized queries to retrieve
    review requests with specific targets or origins, and to create review
    requests based on certain data.
    """

    def create(self, user, repository, changenum=None):
        """
        Creates a new review request, optionally filling in fields based off
        a change number.
        """
        if changenum:
            try:
                review_request = self.get(changenum=changenum,
                                          repository=repository)
                raise ChangeNumberInUseError(review_request)
            except ReviewRequest.DoesNotExist:
                pass

        review_request = ReviewRequest(repository=repository)

        if changenum:
            review_request.update_from_changenum(changenum)

        diffset_history = DiffSetHistory()
        diffset_history.save()

        review_request.diffset_history = diffset_history
        review_request.submitter = user
        review_request.status = 'P'
        review_request.public = False
        review_request.save()

        return review_request

    def public(self, user=None, status='P'):
        return self._query(user, status)

    def to_group(self, group_name, user=None, status='P'):
        return self._query(user, status, Q(target_groups__name=group_name))

    def to_user_groups(self, username, user=None, status='P'):
        return self._query(user, status,
                           Q(target_groups__users__username=username))

    def to_user_directly(self, username, user=None, status='P'):
        query = QLeftOuterJoins(Q(target_people__username=username) |
                                Q(starred_by__user__username=username))
        return self._query(user, status, query)

    def to_user(self, username, user=None, status='P'):
        query = QLeftOuterJoins(Q(target_groups__users__username=username) |
                                Q(target_people__username=username) |
                                Q(starred_by__user__username=username))
        return self._query(user, status, query)

    def from_user(self, username, user=None, status='P'):
        return self._query(user, status, Q(submitter__username=username))

    def _query(self, user, status, extra_query=None):
        query = Q(public=True)

        if user and user.is_authenticated():
            query = query | Q(submitter=user)

        if status:
            query = query & Q(status=status)

        if extra_query:
            query = query & extra_query

        return self.filter(query).distinct()


class ReviewRequest(models.Model):
    STATUSES = (
        ('P', 'Pending Review'),
        ('S', 'Submitted'),
        ('D', 'Discarded'),
    )

    submitter = models.ForeignKey(User, verbose_name="Submitter")
    time_added = models.DateTimeField("Time Added", default=datetime.now)
    last_updated = ModificationTimestampField("Last Updated")
    status = models.CharField(maxlength=1, choices=STATUSES)
    public = models.BooleanField("Public", default=False)
    changenum = models.PositiveIntegerField("Change Number", blank=True,
                                            null=True, db_index=True)
    repository = models.ForeignKey(Repository)
    email_message_id = models.CharField("E-Mail Message ID", maxlength=255,
                                        blank=True, null=True)
    time_emailed = models.DateTimeField("Time E-Mailed", null=True,
                                        default=None, blank=True)

    summary = models.CharField("Summary", maxlength=300, core=True)
    description = models.TextField("Description", blank=True)
    testing_done = models.TextField("Testing Done", blank=True)
    bugs_closed = models.CommaSeparatedIntegerField("Bugs",
                                                    maxlength=300, blank=True)
    diffset_history = models.ForeignKey(DiffSetHistory,
                                        verbose_name='diff set history',
                                        blank=True)
    branch = models.CharField("Branch", maxlength=300, blank=True)
    target_groups = models.ManyToManyField(Group, verbose_name="Target Groups",
                                           core=False, blank=True,
                                           filter_interface=models.HORIZONTAL)
    target_people = models.ManyToManyField(User, verbose_name="Target People",
                                           related_name="directed_review_requests",
                                           core=False, blank=True,
                                           filter_interface=models.HORIZONTAL)
    screenshots = models.ManyToManyField(Screenshot, verbose_name="Screenshots",
                                         related_name="review_request",
                                         core=False, blank=True,
                                         filter_interface=models.VERTICAL)
    inactive_screenshots = models.ManyToManyField(Screenshot,
        related_name="inactive_review_request", core=False, blank=True,
        filter_interface=models.VERTICAL)


    # Set this up with the ReviewRequestManager
    objects = ReviewRequestManager()


    def get_bug_list(self):
        bugs = re.split(r"[, ]+", self.bugs_closed)
        bugs.sort(cmp=lambda x,y: int(x) - int(y))
        return bugs

    def get_new_reviews(self, user):
        """
        Returns any new reviews since the user last viewed the review request.
        """
        if user.is_authenticated():
            visit = get_object_or_none(self.visits, user=user)
{'fraction_non_alphanumeric': 0.09545625706037404, 'fraction_numerical': 0.0031379440190786997, 'mean_word_length': 2.4853455818022745, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '185345', 'n_tokens_mistral': 4365, 'n_tokens_neox': 4190, 'n_words': 924}