-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
api: Add dataclass for update_message events. #18411
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Different variants of update_message events made it difficult to keep api changes uniform across them. Created a dataclass for update_message variant events and refactored to replace Dict with TypedDict. Fixes #16022.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5622,7 +5622,7 @@ def do_update_embedded_data( | |
content: Optional[str], | ||
rendered_content: Optional[str], | ||
) -> None: | ||
event: Dict[str, Any] = {"type": "update_message", "message_id": message.id} | ||
event: UpdateMessagesEvent = {"type": "update_message", "message_id": message.id} | ||
changed_messages = [message] | ||
|
||
ums = UserMessage.objects.filter(message=message.id) | ||
|
@@ -5658,6 +5658,38 @@ class DeleteMessagesEvent(TypedDict, total=False): | |
stream_id: int | ||
|
||
|
||
class UpdateMessagesEvent(TypedDict, total=False): | ||
type: str | ||
user_id: int | ||
message_id: int | ||
message_ids: List[int] | ||
|
||
edit_timestamp: Optional[int] | ||
propagate_mode: Optional[str] | ||
orig_content: Optional[str] | ||
orig_rendered_content: Optional[str] | ||
prev_rendered_content_version: Optional[int] | ||
content: Optional[str] | ||
flags: Optional[List[str]] | ||
is_me_message: Optional[bool] | ||
rendered_content: Optional[str] | ||
|
||
push_notify_user_ids: Optional[List[int]] | ||
stream_push_user_ids: Optional[List[int]] | ||
stream_email_user_ids: Optional[List[int]] | ||
prior_mention_user_ids: Optional[List[int]] | ||
mention_user_ids: Optional[List[int]] | ||
presence_idle_user_ids: Optional[List[int]] | ||
wildcard_mention_user_ids: Optional[List[int]] | ||
|
||
stream_name: Optional[str] | ||
stream_id: Optional[int] | ||
new_stream_id: Optional[int] | ||
orig_subject: Optional[str] | ||
subject: Optional[str] | ||
topic_links: Optional[List[Dict[str, str]]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kinda giant; I wonder if there's a good way to define simpler classes; e.g. have the common elements in a base class, and then subclasses for "has topic edit"? Not sure; in any case, it's an improvement to just have a defined type even if it is giant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, ideally we'd use the class in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I initially tried to do it this way -- but there are total 4 branching There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @timabbott Would this large number of different classes be desirable? Since this is the only way I think we could remove the |
||
|
||
|
||
# We use transaction.atomic to support select_for_update in the attachment codepath. | ||
@transaction.atomic | ||
def do_update_message( | ||
|
@@ -5688,7 +5720,7 @@ def do_update_message( | |
timestamp = timezone_now() | ||
target_message.last_edit_time = timestamp | ||
|
||
event: Dict[str, Any] = { | ||
event: UpdateMessagesEvent = { | ||
"type": "update_message", | ||
"user_id": user_profile.id, | ||
"edit_timestamp": datetime_to_timestamp(timestamp), | ||
|
@@ -5799,7 +5831,8 @@ def do_update_message( | |
assert stream_being_edited is not None | ||
|
||
edit_history_event["prev_stream"] = stream_being_edited.id | ||
event[ORIG_TOPIC] = orig_topic_name | ||
assert ORIG_TOPIC == "orig_subject" | ||
event["orig_subject"] = orig_topic_name | ||
target_message.recipient_id = new_stream.recipient_id | ||
|
||
event["new_stream_id"] = new_stream.id | ||
|
@@ -5854,9 +5887,12 @@ def do_update_message( | |
target_message.set_topic_name(topic_name) | ||
|
||
# These fields have legacy field names. | ||
event[ORIG_TOPIC] = orig_topic_name | ||
event[TOPIC_NAME] = topic_name | ||
event[TOPIC_LINKS] = topic_links(target_message.sender.realm_id, topic_name) | ||
assert ORIG_TOPIC == "orig_subject" | ||
assert TOPIC_NAME == "subject" | ||
assert TOPIC_LINKS == "topic_links" | ||
event["orig_subject"] = orig_topic_name | ||
event["subject"] = topic_name | ||
event["topic_links"] = topic_links(target_message.sender.realm_id, topic_name) | ||
edit_history_event[LEGACY_PREV_TOPIC] = orig_topic_name | ||
|
||
update_edit_history(target_message, timestamp, edit_history_event) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why total=False here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is something I used as a temporary solution and need to fix(hence the current WIP status). Removing it causes error since
message_ids
, which is a compulary field is calculated much later in the code and the event TypedDict is created much before.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@timabbott Something that I now remembered -- the
total=False
is necessary because we need to omit the Optional parameters completely rather than including them withNone
, since the API expects those keys to be absent rather than present with valueNone
, and gives error in such cases.A downside of doing this is that we won't be able to check for missing parameters in the event.(I followed the example of
DeleteMessagesEvent
to usetotal=False
)