95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
import logging
|
|
|
|
from django.core.files.base import ContentFile
|
|
from django.db import transaction
|
|
from django.db.models.signals import post_delete, post_save, pre_save
|
|
from django.dispatch import receiver
|
|
|
|
from common.image_utils import compress_avatar
|
|
|
|
from .models import Task, TaskActivity, TaskAttachment, TaskBoard
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _delete_file_after_commit(field_file):
|
|
if not field_file or not field_file.name:
|
|
return
|
|
storage = field_file.storage
|
|
name = field_file.name
|
|
transaction.on_commit(
|
|
lambda: storage.delete(name) if storage.exists(name) else None
|
|
)
|
|
|
|
|
|
@receiver(pre_save, sender=TaskBoard)
|
|
def compress_and_cleanup_task_board_avatar(sender, instance, **kwargs):
|
|
old_avatar = None
|
|
if instance.pk:
|
|
old_avatar = (
|
|
sender.objects.filter(pk=instance.pk)
|
|
.only("avatar")
|
|
.values_list("avatar", flat=True)
|
|
.first()
|
|
)
|
|
|
|
new_avatar = instance.avatar
|
|
if new_avatar and not getattr(new_avatar, "_committed", True):
|
|
try:
|
|
compressed = compress_avatar(new_avatar.read())
|
|
if compressed:
|
|
new_avatar.save(
|
|
new_avatar.name,
|
|
ContentFile(compressed),
|
|
save=False,
|
|
)
|
|
except Exception:
|
|
new_avatar.seek(0)
|
|
logger.exception(
|
|
"Task board avatar compression failed",
|
|
extra={
|
|
"event": "task.board.avatar.compression_failed",
|
|
"task_board_id": instance.pk,
|
|
},
|
|
)
|
|
|
|
new_avatar_name = new_avatar.name if new_avatar else None
|
|
if old_avatar and old_avatar != new_avatar_name:
|
|
storage = instance._meta.get_field("avatar").storage
|
|
transaction.on_commit(
|
|
lambda: storage.delete(old_avatar) if storage.exists(old_avatar) else None
|
|
)
|
|
|
|
|
|
@receiver(post_delete, sender=TaskBoard)
|
|
def delete_task_board_avatar(sender, instance, **kwargs):
|
|
_delete_file_after_commit(instance.avatar)
|
|
|
|
|
|
@receiver(post_save, sender=Task)
|
|
def ensure_task_core_participants(sender, instance, **kwargs):
|
|
participant_ids = [instance.created_by_id]
|
|
if instance.assignee_id:
|
|
participant_ids.append(instance.assignee_id)
|
|
instance.participants.add(*participant_ids)
|
|
|
|
|
|
@receiver(post_delete, sender=TaskAttachment)
|
|
def delete_task_attachment_file(sender, instance, **kwargs):
|
|
_delete_file_after_commit(instance.file)
|
|
|
|
|
|
@receiver(post_save, sender=TaskActivity)
|
|
def dispatch_task_automation_event(sender, instance, created, **kwargs):
|
|
if not created:
|
|
return
|
|
|
|
activity_id = instance.id
|
|
|
|
def dispatch():
|
|
from tasks.tasks import process_task_automation_event_task
|
|
|
|
process_task_automation_event_task.delay(activity_id)
|
|
|
|
transaction.on_commit(dispatch)
|