from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.db.models.signals import post_delete, post_save, pre_delete from django.dispatch import receiver from schedule.models import Calendar, Event from .realtime import get_calendar_recipient_ids, send_calendar_update def _relation_user_id(instance) -> int | None: User = get_user_model() user_content_type = ContentType.objects.get_for_model(User) if instance.content_type_id != user_content_type.id: return None return instance.object_id @receiver(post_save, sender="schedule.Event") def broadcast_event_saved(sender, instance, created, **kwargs): calendar = instance.calendar send_calendar_update( action="created" if created else "updated", entity="event", calendar_id=calendar.id, event_id=instance.id, changed_fields=getattr(instance, "_changed_fields", []), recipient_ids=get_calendar_recipient_ids(calendar, event=instance), extra={ "start": instance.start.isoformat() if instance.start else None, "end": instance.end.isoformat() if instance.end else None, "is_recurring": bool(instance.rule_id), }, ) @receiver(pre_delete, sender="schedule.Event") def broadcast_event_deleted(sender, instance, **kwargs): send_calendar_update( action="deleted", entity="event", calendar_id=instance.calendar_id, event_id=instance.id, recipient_ids=get_calendar_recipient_ids(instance.calendar, event=instance), extra={ "start": instance.start.isoformat() if instance.start else None, "end": instance.end.isoformat() if instance.end else None, "is_recurring": bool(instance.rule_id), }, ) @receiver(post_save, sender="schedule.Calendar") def broadcast_calendar_saved(sender, instance, created, **kwargs): recipients = get_calendar_recipient_ids(instance) if not recipients: return send_calendar_update( action="created" if created else "updated", entity="calendar", calendar_id=instance.id, recipient_ids=recipients, ) @receiver(pre_delete, sender="schedule.Calendar") def broadcast_calendar_deleted(sender, instance, **kwargs): send_calendar_update( action="deleted", entity="calendar", calendar_id=instance.id, recipient_ids=get_calendar_recipient_ids(instance), ) @receiver(post_save, sender="schedule.CalendarRelation") def broadcast_calendar_relation_saved(sender, instance, **kwargs): recipients = get_calendar_recipient_ids(instance.calendar) relation_user_id = _relation_user_id(instance) if relation_user_id: recipients.add(relation_user_id) send_calendar_update( action="membership_changed", entity="calendar", calendar_id=instance.calendar_id, recipient_ids=recipients, ) @receiver(post_delete, sender="schedule.CalendarRelation") def broadcast_calendar_relation_deleted(sender, instance, **kwargs): calendar = Calendar.objects.filter(pk=instance.calendar_id).first() recipients = get_calendar_recipient_ids(calendar) relation_user_id = _relation_user_id(instance) if relation_user_id: recipients.add(relation_user_id) send_calendar_update( action="membership_changed", entity="calendar", calendar_id=instance.calendar_id, recipient_ids=recipients, ) @receiver([post_save, post_delete], sender="schedule.EventRelation") def broadcast_event_relation_changed(sender, instance, **kwargs): event = ( Event.objects.select_related("calendar").filter(pk=instance.event_id).first() ) if event is None: return recipients = get_calendar_recipient_ids(event.calendar, event=event) relation_user_id = _relation_user_id(instance) if relation_user_id: recipients.add(relation_user_id) send_calendar_update( action="membership_changed", entity="event", calendar_id=event.calendar_id, event_id=event.id, recipient_ids=recipients, )