mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	django-stubs 4.2.1 gives transaction.on_commit a more accurate type
annotation, but this exposed that mypy can’t handle the lambda default
parameters that we use to recapture loop variables such as
    for stream_id in public_stream_ids:
        peer_user_ids = …
        event = …
        transaction.on_commit(
            lambda event=event, peer_user_ids=peer_user_ids: send_event(
                realm, event, peer_user_ids
            )
        )
https://github.com/python/mypy/issues/15459
A workaround that mypy accepts is
        transaction.on_commit(
            (
                lambda event, peer_user_ids: lambda: send_event(
                    realm, event, peer_user_ids
                )
            )(event, peer_user_ids)
        )
But that’s kind of ugly and potentially error-prone, so let’s make a
helper function for this very common pattern.
        send_event_on_commit(realm, event, peer_user_ids)
Signed-off-by: Anders Kaseorg <anders@zulip.com>
(cherry picked from commit 7657cb4a0f)
		
	
		
			
				
	
	
		
			66 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from typing import Iterable, List, TypedDict
 | 
						|
 | 
						|
from zerver.lib import retention
 | 
						|
from zerver.lib.retention import move_messages_to_archive
 | 
						|
from zerver.lib.stream_subscription import get_active_subscriptions_for_stream_id
 | 
						|
from zerver.models import Message, Realm, UserMessage, UserProfile
 | 
						|
from zerver.tornado.django_api import send_event_on_commit
 | 
						|
 | 
						|
 | 
						|
class DeleteMessagesEvent(TypedDict, total=False):
 | 
						|
    type: str
 | 
						|
    message_ids: List[int]
 | 
						|
    message_type: str
 | 
						|
    topic: str
 | 
						|
    stream_id: int
 | 
						|
 | 
						|
 | 
						|
def do_delete_messages(realm: Realm, messages: Iterable[Message]) -> None:
 | 
						|
    # messages in delete_message event belong to the same topic
 | 
						|
    # or is a single private message, as any other behaviour is not possible with
 | 
						|
    # the current callers to this method.
 | 
						|
    messages = list(messages)
 | 
						|
    message_ids = [message.id for message in messages]
 | 
						|
    if not message_ids:
 | 
						|
        return
 | 
						|
 | 
						|
    event: DeleteMessagesEvent = {
 | 
						|
        "type": "delete_message",
 | 
						|
        "message_ids": message_ids,
 | 
						|
    }
 | 
						|
 | 
						|
    sample_message = messages[0]
 | 
						|
    message_type = "stream"
 | 
						|
    users_to_notify = []
 | 
						|
    if not sample_message.is_stream_message():
 | 
						|
        assert len(messages) == 1
 | 
						|
        message_type = "private"
 | 
						|
        ums = UserMessage.objects.filter(message_id__in=message_ids)
 | 
						|
        users_to_notify = [um.user_profile_id for um in ums]
 | 
						|
        archiving_chunk_size = retention.MESSAGE_BATCH_SIZE
 | 
						|
 | 
						|
    if message_type == "stream":
 | 
						|
        stream_id = sample_message.recipient.type_id
 | 
						|
        event["stream_id"] = stream_id
 | 
						|
        event["topic"] = sample_message.topic_name()
 | 
						|
        subscriptions = get_active_subscriptions_for_stream_id(
 | 
						|
            stream_id, include_deactivated_users=False
 | 
						|
        )
 | 
						|
        # We exclude long-term idle users, since they by definition have no active clients.
 | 
						|
        subscriptions = subscriptions.exclude(user_profile__long_term_idle=True)
 | 
						|
        users_to_notify = list(subscriptions.values_list("user_profile_id", flat=True))
 | 
						|
        archiving_chunk_size = retention.STREAM_MESSAGE_BATCH_SIZE
 | 
						|
 | 
						|
    move_messages_to_archive(message_ids, realm=realm, chunk_size=archiving_chunk_size)
 | 
						|
 | 
						|
    event["message_type"] = message_type
 | 
						|
    send_event_on_commit(realm, event, users_to_notify)
 | 
						|
 | 
						|
 | 
						|
def do_delete_messages_by_sender(user: UserProfile) -> None:
 | 
						|
    message_ids = list(
 | 
						|
        Message.objects.filter(sender=user).values_list("id", flat=True).order_by("id")
 | 
						|
    )
 | 
						|
    if message_ids:
 | 
						|
        move_messages_to_archive(message_ids, chunk_size=retention.STREAM_MESSAGE_BATCH_SIZE)
 |