mirror of
https://github.com/zulip/zulip.git
synced 2025-11-15 11:22:04 +00:00
types: Add EditHistoryEvent and APIEditHistoryEvent types.
These types will help make iteration on this code easier. Note that `user_id` can be null due to the fact that edit history entries before March 2017 did not log the user that made the edit, which was years after supporting topic edits (discovered in test deployment of migration on chat.zulip.org). Co-authored-by: Lauryn Menard <lauryn.menard@gmail.com>
This commit is contained in:
@@ -13,6 +13,7 @@ from zulint.custom_rules import Rule, RuleList
|
||||
FILES_WITH_LEGACY_SUBJECT = {
|
||||
# This basically requires a big DB migration:
|
||||
"zerver/lib/topic.py",
|
||||
"zerver/lib/types.py",
|
||||
# This is for backward compatibility.
|
||||
"zerver/tests/test_legacy_subject.py",
|
||||
# Other migration-related changes require extreme care.
|
||||
@@ -229,7 +230,7 @@ python_rules = RuleList(
|
||||
rules=[
|
||||
{
|
||||
"pattern": "subject|SUBJECT",
|
||||
"exclude_pattern": "subject to the|email|outbox",
|
||||
"exclude_pattern": "subject to the|email|outbox|edit_history_event",
|
||||
"description": "avoid subject as a var",
|
||||
"good_lines": ["topic_name"],
|
||||
"bad_lines": ['subject="foo"', " MAX_SUBJECT_LEN"],
|
||||
|
||||
@@ -161,7 +161,6 @@ from zerver.lib.string_validation import check_stream_name, check_stream_topic
|
||||
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
|
||||
from zerver.lib.timezone import canonicalize_timezone
|
||||
from zerver.lib.topic import (
|
||||
LEGACY_PREV_TOPIC,
|
||||
ORIG_TOPIC,
|
||||
RESOLVED_TOPIC_PREFIX,
|
||||
TOPIC_LINKS,
|
||||
@@ -174,7 +173,12 @@ from zerver.lib.topic import (
|
||||
update_messages_for_topic_edit,
|
||||
)
|
||||
from zerver.lib.topic_mutes import add_topic_mute, get_topic_mutes, remove_topic_mute
|
||||
from zerver.lib.types import ProfileDataElementValue, ProfileFieldData, UnspecifiedValue
|
||||
from zerver.lib.types import (
|
||||
EditHistoryEvent,
|
||||
ProfileDataElementValue,
|
||||
ProfileFieldData,
|
||||
UnspecifiedValue,
|
||||
)
|
||||
from zerver.lib.upload import (
|
||||
claim_attachment,
|
||||
delete_avatar_image,
|
||||
@@ -6695,7 +6699,7 @@ def do_update_message(
|
||||
"rendering_only": False,
|
||||
}
|
||||
|
||||
edit_history_event: Dict[str, Any] = {
|
||||
edit_history_event: EditHistoryEvent = {
|
||||
"user_id": user_profile.id,
|
||||
"timestamp": event["edit_timestamp"],
|
||||
}
|
||||
@@ -6869,7 +6873,7 @@ def do_update_message(
|
||||
event[ORIG_TOPIC] = orig_topic_name
|
||||
event[TOPIC_NAME] = topic_name
|
||||
event[TOPIC_LINKS] = topic_links(target_message.sender.realm_id, topic_name)
|
||||
edit_history_event[LEGACY_PREV_TOPIC] = orig_topic_name
|
||||
edit_history_event["prev_subject"] = orig_topic_name
|
||||
|
||||
update_edit_history(target_message, timestamp, edit_history_event)
|
||||
|
||||
@@ -6879,16 +6883,14 @@ def do_update_message(
|
||||
assert stream_being_edited is not None
|
||||
|
||||
# Other messages should only get topic/stream fields in their edit history.
|
||||
topic_only_edit_history_event = {
|
||||
k: v
|
||||
for (k, v) in edit_history_event.items()
|
||||
if k
|
||||
not in [
|
||||
"prev_content",
|
||||
"prev_rendered_content",
|
||||
"prev_rendered_content_version",
|
||||
]
|
||||
topic_only_edit_history_event: EditHistoryEvent = {
|
||||
"user_id": edit_history_event["user_id"],
|
||||
"timestamp": edit_history_event["timestamp"],
|
||||
}
|
||||
if topic_name is not None:
|
||||
topic_only_edit_history_event["prev_subject"] = edit_history_event["prev_subject"]
|
||||
if new_stream is not None:
|
||||
topic_only_edit_history_event["prev_stream"] = edit_history_event["prev_stream"]
|
||||
|
||||
messages_list = update_messages_for_topic_edit(
|
||||
acting_user=user_profile,
|
||||
|
||||
@@ -38,7 +38,7 @@ from zerver.lib.streams import get_web_public_streams_queryset
|
||||
from zerver.lib.timestamp import datetime_to_timestamp
|
||||
from zerver.lib.topic import DB_TOPIC_NAME, MESSAGE__TOPIC, TOPIC_LINKS, TOPIC_NAME
|
||||
from zerver.lib.topic_mutes import build_topic_mute_checker, topic_is_muted
|
||||
from zerver.lib.types import DisplayRecipientT, UserDisplayRecipient
|
||||
from zerver.lib.types import DisplayRecipientT, EditHistoryEvent, UserDisplayRecipient
|
||||
from zerver.models import (
|
||||
MAX_TOPIC_NAME_LENGTH,
|
||||
Message,
|
||||
@@ -502,7 +502,8 @@ class MessageDict:
|
||||
if last_edit_time is not None:
|
||||
obj["last_edit_timestamp"] = datetime_to_timestamp(last_edit_time)
|
||||
assert edit_history_json is not None
|
||||
edit_history = orjson.loads(edit_history_json)
|
||||
# Here we assume EditHistoryEvent == APIEditHistoryEvent
|
||||
edit_history: List[EditHistoryEvent] = orjson.loads(edit_history_json)
|
||||
obj["edit_history"] = edit_history
|
||||
|
||||
if Message.need_to_render_content(
|
||||
|
||||
@@ -8,6 +8,7 @@ from sqlalchemy.sql import ColumnElement, column, func, literal
|
||||
from sqlalchemy.types import Boolean, Text
|
||||
|
||||
from zerver.lib.request import REQ
|
||||
from zerver.lib.types import EditHistoryEvent
|
||||
from zerver.models import Message, Stream, UserMessage, UserProfile
|
||||
|
||||
# Only use these constants for events.
|
||||
@@ -135,11 +136,11 @@ def user_message_exists_for_topic(
|
||||
|
||||
|
||||
def update_edit_history(
|
||||
message: Message, last_edit_time: datetime, edit_history_event: Dict[str, Any]
|
||||
message: Message, last_edit_time: datetime, edit_history_event: EditHistoryEvent
|
||||
) -> None:
|
||||
message.last_edit_time = last_edit_time
|
||||
if message.edit_history is not None:
|
||||
edit_history = orjson.loads(message.edit_history)
|
||||
edit_history: List[EditHistoryEvent] = orjson.loads(message.edit_history)
|
||||
edit_history.insert(0, edit_history_event)
|
||||
else:
|
||||
edit_history = [edit_history_event]
|
||||
@@ -154,7 +155,7 @@ def update_messages_for_topic_edit(
|
||||
topic_name: Optional[str],
|
||||
new_stream: Optional[Stream],
|
||||
old_stream: Stream,
|
||||
edit_history_event: Dict[str, Any],
|
||||
edit_history_event: EditHistoryEvent,
|
||||
last_edit_time: datetime,
|
||||
) -> List[Message]:
|
||||
propagate_query = Q(recipient_id=old_stream.recipient_id, subject__iexact=orig_topic_name)
|
||||
|
||||
@@ -89,3 +89,40 @@ class UnspecifiedValue:
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class APIEditHistoryEvent(TypedDict, total=False):
|
||||
"""Format of legacy edit history events in the API. Contains legacy
|
||||
fields like LEGACY_PREV_TOPIC that we intend to remove from the
|
||||
API eventually.
|
||||
"""
|
||||
|
||||
# Commented fields are fields we plan to add.
|
||||
user_id: Optional[int]
|
||||
timestamp: int
|
||||
prev_stream: int
|
||||
# stream: int
|
||||
prev_subject: str
|
||||
# prev_topic: str
|
||||
# topic: str
|
||||
prev_content: str
|
||||
prev_rendered_content: Optional[str]
|
||||
prev_rendered_content_version: Optional[int]
|
||||
|
||||
|
||||
class EditHistoryEvent(TypedDict, total=False):
|
||||
"""
|
||||
Database format for edit history events.
|
||||
"""
|
||||
|
||||
# Commented fields are fields we plan to add.
|
||||
user_id: Optional[int]
|
||||
timestamp: int
|
||||
prev_stream: int
|
||||
# stream: int
|
||||
prev_subject: str
|
||||
# prev_topic: str
|
||||
# topic: str
|
||||
prev_content: str
|
||||
prev_rendered_content: Optional[str]
|
||||
prev_rendered_content_version: Optional[int]
|
||||
|
||||
Reference in New Issue
Block a user