<commit_before>import cgi
from collections import namedtuple

from django.urls import reverse
from django.utils.html import format_html
from django.utils.translation import ugettext as _

from corehq.apps.data_interfaces.models import AutomaticUpdateRule
from corehq.apps.sms.models import (
    INCOMING,
    OUTGOING,
    SMS,
    WORKFLOW_FORWARD,
    Keyword,
    MessagingEvent,
    MessagingSubEvent,
)
from corehq.messaging.scheduling.models import (
    ImmediateBroadcast,
    MigratedReminder,
    ScheduledBroadcast,
)
from corehq.messaging.scheduling.views import (
    EditConditionalAlertView,
    EditScheduleView,
)
from corehq.util.quickcache import quickcache


def get_status_display(event, sms=None):
    """
    event can be a MessagingEvent or MessagingSubEvent
    """
    # If sms without error, short circuit to the sms status display
    if event.status != MessagingEvent.STATUS_ERROR and sms:
        return get_sms_status_display(sms)

    # If survey without error, short circuit to the survey status display
    if (isinstance(event, MessagingSubEvent) and
            event.status == MessagingEvent.STATUS_COMPLETED and
            event.xforms_session_id):
        return _(event.xforms_session.status)

    status = event.status
    error_code = event.error_code

    # If we have a MessagingEvent with no error_code it means there's
    # an error in the subevent
    if status == MessagingEvent.STATUS_ERROR and not error_code:
        error_code = MessagingEvent.ERROR_SUBEVENT_ERROR

    # If we have a MessagingEvent that's completed but it's tied to
    # unfinished surveys, then mark it as being in progress
    if (
        isinstance(event, MessagingEvent) and
        event.status == MessagingEvent.STATUS_COMPLETED and
        MessagingSubEvent.objects.filter(
            parent_id=event.pk,
            content_type=MessagingEvent.CONTENT_SMS_SURVEY,
            # without this line, django does a left join which is not what we want
            xforms_session_id__isnull=False,
            xforms_session__session_is_open=True
        ).count() > 0
    ):
        status = MessagingEvent.STATUS_IN_PROGRESS

    status = dict(MessagingEvent.STATUS_CHOICES).get(status, '-')
    error_message = (MessagingEvent.ERROR_MESSAGES.get(error_code, None)
                     if error_code else None)
    error_message = _(error_message) if error_message else ''
    if event.additional_error_text:
        error_message += ' %s' % event.additional_error_text

    # Sometimes the additional information from touchforms has < or >
    # characters, so we need to escape them for display
    if error_message:
        return '%s - %s' % (_(status), cgi.escape(error_message))
    else:
        return _(status)


def get_sms_status_display(sms):
    slug, detail = get_sms_status_display_raw(sms)
    display = SMS.STATUS_DISPLAY[slug]
    detail = f" - {detail}" if detail else ""
    return f"{display}{detail}"

<commit_msg>Use html.escape instead of cgi.escape<commit_after>import html
from collections import namedtuple

from django.urls import reverse
from django.utils.html import format_html
from django.utils.translation import ugettext as _

from corehq.apps.data_interfaces.models import AutomaticUpdateRule
from corehq.apps.sms.models import (
    INCOMING,
    OUTGOING,
    SMS,
    WORKFLOW_FORWARD,
    Keyword,
    MessagingEvent,
    MessagingSubEvent,
)
from corehq.messaging.scheduling.models import (
    ImmediateBroadcast,
    MigratedReminder,
    ScheduledBroadcast,
)
from corehq.messaging.scheduling.views import (
    EditConditionalAlertView,
    EditScheduleView,
)
from corehq.util.quickcache import quickcache


def get_status_display(event, sms=None):
    """
    event can be a MessagingEvent or MessagingSubEvent
    """
    # If sms without error, short circuit to the sms status display
    if event.status != MessagingEvent.STATUS_ERROR and sms:
        return get_sms_status_display(sms)

    # If survey without error, short circuit to the survey status display
    if (isinstance(event, MessagingSubEvent) and
            event.status == MessagingEvent.STATUS_COMPLETED and
            event.xforms_session_id):
        return _(event.xforms_session.status)

    status = event.status
    error_code = event.error_code

    # If we have a MessagingEvent with no error_code it means there's
    # an error in the subevent
    if status == MessagingEvent.STATUS_ERROR and not error_code:
        error_code = MessagingEvent.ERROR_SUBEVENT_ERROR

    # If we have a MessagingEvent that's completed but it's tied to
    # unfinished surveys, then mark it as being in progress
    if (
        isinstance(event, MessagingEvent) and
        event.status == MessagingEvent.STATUS_COMPLETED and
        MessagingSubEvent.objects.filter(
            parent_id=event.pk,
            content_type=MessagingEvent.CONTENT_SMS_SURVEY,
            # without this line, django does a left join which is not what we want
            xforms_session_id__isnull=False,
            xforms_session__session_is_open=True
        ).count() > 0
    ):
        status = MessagingEvent.STATUS_IN_PROGRESS

    status = dict(MessagingEvent.STATUS_CHOICES).get(status, '-')
    error_message = (MessagingEvent.ERROR_MESSAGES.get(error_code, None)
                     if error_code else None)
    error_message = _(error_message) if error_message else ''
    if event.additional_error_text:
        error_message += ' %s' % event.additional_error_text

    # Sometimes the additional information from touchforms has < or >
    # characters, so we need to escape them for display
    if error_message:
        return '%s - %s' % (_(status), html.escape(error_message))
    else:
        return _(status)


def get_sms_status_display(sms):
    slug, detail = get_sms_status_display_raw(sms)
    display = SMS.STATUS_DISPLAY[slug]
    detail = f" - {detail}" if detail else ""
    return f"{display}{detail}"


{'fraction_non_alphanumeric': 0.06982208794897617, 'fraction_numerical': 0.0003356831151393085, 'mean_word_length': 3.253390435403283, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, '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': '6955918', 'n_tokens_mistral': 1794, 'n_tokens_neox': 1744, 'n_words': 476}