<commit_before>from django import template
from django.conf import settings
from django.db.models import Q
from django.template import NodeList, TemplateSyntaxError
from django.template.loader import render_to_string
from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _
from djblets.util.decorators import basictag, blocktag
from djblets.util.misc import get_object_or_none
from djblets.util.templatetags.djblets_utils import humanize_list

from reviewboard.accounts.models import Profile
from reviewboard.diffviewer.models import DiffSet
from reviewboard.reviews.models import BaseComment, Comment, Group, \
                                       ReviewRequest, ScreenshotComment, \
                                       FileAttachmentComment


register = template.Library()


@register.tag
@blocktag
def forcomment(context, nodelist, filediff, review=None):
    """
    Loops over a list of comments beloning to a filediff.

    This will populate a special ``comment`` variable for use in the content.
    This is of the type :model:`reviews.Comment`.
    """
    new_nodelist = NodeList()
    context.push()

    if not review:
        comments = filediff.comments.all()
    else:
        comments = filediff.comments.filter(review=review)

    for comment in comments:
        context['comment'] = comment

        for node in nodelist:
            new_nodelist.append(node.render(context))

    context.pop()
    return new_nodelist.render(context)


@register.tag
@blocktag
def ifneatnumber(context, nodelist, rid):
    """
    Returns whether or not the specified number is a "neat" number.
    This is a number with a special property, such as being a
    palindrome or having trailing zeroes.

    If the number is a neat number, the contained content is rendered,
    and two variables, ``milestone`` and ``palindrome`` are defined.
    """
    if rid == None or rid < 1000:
        return ""

    ridstr = str(rid)
    interesting = False

    context.push()
    context['milestone'] = False
    context['palindrome'] = False

    if rid >= 1000:
        trailing = ridstr[1:]
        if trailing == "0" * len(trailing):
            context['milestone'] = True
            interesting = True

    if not interesting:
        if ridstr == ''.join(reversed(ridstr)):
            context['palindrome'] = True
            interesting = True

    if not interesting:
        context.pop()
        return ""

    s = nodelist.render(context)
    context.pop()
    return s


@register.tag
@basictag(takes_context=True)
def commentcounts(context, filediff, interfilediff=None):
    """
    Returns a JSON array of current comments for a filediff, sorted by
    line number.

    Each entry in the array has a dictionary containing the following keys:

      =========== ==================================================
      Key                Description
      =========== ==================================================
      comment_id         The ID of the comment
      text               The text of the comment
      line               The first line number
      num_lines          The number of lines this comment spans
      user               A dictionary containing "username" and "name" keys
                         for the user
      url                The URL to the comment
      localdraft         True if this is the current user's draft comment
      review_id          The ID of the review this comment is associated with
      ==============================================================
    """
    comment_dict = {}
    user = context.get('user', None)

    if interfilediff:
        query = Comment.objects.filter(filediff=filediff,
                                       interfilediff=interfilediff)
    else:
        query = Comment.objects.filter(filediff=filediff,
                                       interfilediff__isnull=True)

    for comment in query:
        review = get_object_or_none(comment.review)

        if review and (review.public or review.user == user):
            key = (comment.first_line, comment.num_lines)

            comment_dict.setdefault(key, []).append({
                'comment_id': comment.id,
                'text': comment.text,
                'points_deducted': comment.points_deducted,
                'line': comment.first_line,
                'num_lines': comment.num_lines,
                'user': {
                    'username': review.user.username,
                    'name': review.user.get_full_name() or review.user.username,
                },
                #'timestamp': comment.timestamp,
                'url': comment.get_review_url(),<commit_msg>Check for review.is_accessible_by for inline diff<commit_after>from django import template
from django.conf import settings
from django.db.models import Q
from django.template import NodeList, TemplateSyntaxError
from django.template.loader import render_to_string
from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _
from djblets.util.decorators import basictag, blocktag
from djblets.util.misc import get_object_or_none
from djblets.util.templatetags.djblets_utils import humanize_list

from reviewboard.accounts.models import Profile
from reviewboard.diffviewer.models import DiffSet
from reviewboard.reviews.models import BaseComment, Comment, Group, \
                                       ReviewRequest, ScreenshotComment, \
                                       FileAttachmentComment


register = template.Library()


@register.tag
@blocktag
def forcomment(context, nodelist, filediff, review=None):
    """
    Loops over a list of comments beloning to a filediff.

    This will populate a special ``comment`` variable for use in the content.
    This is of the type :model:`reviews.Comment`.
    """
    new_nodelist = NodeList()
    context.push()

    if not review:
        comments = filediff.comments.all()
    else:
        comments = filediff.comments.filter(review=review)

    for comment in comments:
        context['comment'] = comment

        for node in nodelist:
            new_nodelist.append(node.render(context))

    context.pop()
    return new_nodelist.render(context)


@register.tag
@blocktag
def ifneatnumber(context, nodelist, rid):
    """
    Returns whether or not the specified number is a "neat" number.
    This is a number with a special property, such as being a
    palindrome or having trailing zeroes.

    If the number is a neat number, the contained content is rendered,
    and two variables, ``milestone`` and ``palindrome`` are defined.
    """
    if rid == None or rid < 1000:
        return ""

    ridstr = str(rid)
    interesting = False

    context.push()
    context['milestone'] = False
    context['palindrome'] = False

    if rid >= 1000:
        trailing = ridstr[1:]
        if trailing == "0" * len(trailing):
            context['milestone'] = True
            interesting = True

    if not interesting:
        if ridstr == ''.join(reversed(ridstr)):
            context['palindrome'] = True
            interesting = True

    if not interesting:
        context.pop()
        return ""

    s = nodelist.render(context)
    context.pop()
    return s


@register.tag
@basictag(takes_context=True)
def commentcounts(context, filediff, interfilediff=None):
    """
    Returns a JSON array of current comments for a filediff, sorted by
    line number.

    Each entry in the array has a dictionary containing the following keys:

      =========== ==================================================
      Key                Description
      =========== ==================================================
      comment_id         The ID of the comment
      text               The text of the comment
      line               The first line number
      num_lines          The number of lines this comment spans
      user               A dictionary containing "username" and "name" keys
                         for the user
      url                The URL to the comment
      localdraft         True if this is the current user's draft comment
      review_id          The ID of the review this comment is associated with
      ==============================================================
    """
    comment_dict = {}
    user = context.get('user', None)

    if interfilediff:
        query = Comment.objects.filter(filediff=filediff,
                                       interfilediff=interfilediff)
    else:
        query = Comment.objects.filter(filediff=filediff,
                                       interfilediff__isnull=True)

    for comment in query:
        review = get_object_or_none(comment.review)

        if review and (review.public or review.user == user) and \
           (review.is_accessible_by(user)):
            key = (comment.first_line, comment.num_lines)

            comment_dict.setdefault(key, []).append({
                'comment_id': comment.id,
                'text': comment.text,
                'points_deducted': comment.points_deducted,
                'line': comment.first_line,
                'num_lines': comment.num_lines,
                'user': {
                    'username': review.user.username,
                    'name': review.user.get_full_name() or review.user.username,
                },
                #'timestamp': comment.timestamp,
                'url': comment.get_review_url(),
{'fraction_non_alphanumeric': 0.11360033815914615, 'fraction_numerical': 0.002113494663425975, 'mean_word_length': 2.2941176470588234, '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': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7581106', 'n_tokens_mistral': 2511, 'n_tokens_neox': 2344, 'n_words': 754}