<commit_before># coding: utf-8
import logging
from django.db.models.signals import pre_delete
from django.dispatch import receiver

from onadata.apps.logger.models.attachment import Attachment


@receiver(pre_delete, sender=Attachment)
def pre_delete_attachment(instance, **kwargs):
    # "Model.delete() isn’t called on related models, but the pre_delete and
    # post_delete signals are sent for all deleted objects." See
    # https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.CASCADE
    # We want to delete all files when an Instance (or Attachment) object is
    # deleted.

    # `instance` here means "model instance", and no, it is not allowed to
    # change the name of the parameter
    attachment = instance
    try:
        attachment.media_file.delete()
    except Exception as e:
        logging.error('Failed to delete attachment: ' + str(e), exc_info=True)<commit_msg>Created signals to add and remove attachment sizes to attachment_storage_bytes counts<commit_after># coding: utf-8
import logging

from django.db.models import F
from django.db.models.signals import (
    pre_delete,
    post_save,
)
from django.dispatch import receiver

from onadata.apps.logger.models.attachment import Attachment
from onadata.apps.logger.models.xform import XForm
from onadata.apps.main.models.user_profile import UserProfile


@receiver(pre_delete, sender=Attachment)
def delete_user_profile_attachment_storage_bytes(instance, **kwargs):
    """
    Update the attachment_storage_bytes field in the UserProfile model
    when an attachment is deleted
    """
    file_size = instance.media_file.size
    owner_profile = instance.instance.xform.user.profile.pk
    queryset = UserProfile.objects.filter(pk=owner_profile)
    queryset.update(
        attachment_storage_bytes=F('attachment_storage_bytes') - file_size
    )


@receiver(pre_delete, sender=Attachment)
def delete_xform_attachment_storage_bytes(instance, **kwargs):
    """
    Update the attachment_storage_bytes field in the XForm
    model when an attachment is deleted
    """
    file_size = instance.media_file.size
    xform = instance.instance.xform.pk
    queryset = XForm.objects.filter(pk=xform)
    queryset.update(
        attachment_storage_bytes=F('attachment_storage_bytes') - file_size
    )


@receiver(pre_delete, sender=Attachment)
def pre_delete_attachment(instance, **kwargs):
    # "Model.delete() isn’t called on related models, but the pre_delete and
    # post_delete signals are sent for all deleted objects." See
    # https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.CASCADE
    # We want to delete all files when an Instance (or Attachment) object is
    # deleted.

    # `instance` here means "model instance", and no, it is not allowed to
    # change the name of the parameter
    attachment = instance
    try:
        attachment.media_file.delete()
    except Exception as e:
        logging.error('Failed to delete attachment: ' + str(e), exc_info=True)


@receiver(post_save, sender=Attachment)
def update_user_profile_attachment_storage_bytes(instance, created, **kwargs):
    """
    Update the attachment_storage_bytes field in the UserProfile model
    when an attachment is added
    """
    if not created:
        return
    # Probably not necessary right now, but in case needed in the future
    if getattr(instance, 'defer_counting', False):
        return
    file_size = instance.media_file.size
    user_profile = instance.instance.xform.user.profile.pk
    queryset = UserProfile.objects.filter(pk=user_profile)
    queryset.update(
        attachment_storage_bytes=F('attachment_storage_bytes') + file_size
    )


@receiver(post_save, sender=Attachment)
def update_xform_attachment_storage_bytes(instance, created, **kwargs):
    """
    Update the attachment_storage_bytes field in the XForm model when
    an attachment is added
    """
    if not created:
        return
    # Probably not needed now, but in case needed in the future
    if getattr(instance, 'defer_counting', False):
        return
    file_size = instance.media_file.size
    xform = instance.instance.xform.pk
    queryset = XForm.objects.filter(pk=xform)
    queryset.update(
        attachment_storage_bytes=F('attachment_storage_bytes') + file_size
    )
{'fraction_non_alphanumeric': 0.08410780669144981, 'fraction_numerical': 0.0013940520446096654, 'mean_word_length': 3.914383561643836, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2110880', 'n_tokens_mistral': 1231, 'n_tokens_neox': 1223, 'n_words': 349}