Skip to content

Commit 9d9ef85

Browse files
committed
api: Use batch-based narrow updates for marking messages as read.
Fixes #820.
1 parent 9960360 commit 9d9ef85

1 file changed

Lines changed: 69 additions & 1 deletion

File tree

zulip/zulip/__init__.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import traceback
1111
import types
1212
import urllib.parse
13+
import warnings
1314
from configparser import ConfigParser
1415
from datetime import datetime
1516
from typing import (
@@ -901,19 +902,59 @@ def delete_message(self, message_id: int) -> Dict[str, Any]:
901902
"""
902903
return self.call_endpoint(url=f"messages/{message_id}", method="DELETE")
903904

905+
def update_message_flags_for_narrow(self, update_data: Dict[str, Any]) -> Dict[str, Any]:
906+
"""
907+
See https://zulip.com/api/update-message-flags-for-narrow for usage.
908+
"""
909+
return self.call_endpoint(url="messages/flags/narrow", method="POST", request=update_data)
910+
904911
def update_message_flags(self, update_data: Dict[str, Any]) -> Dict[str, Any]:
905912
"""
906913
See examples/update-flags for example usage.
907914
"""
908915
return self.call_endpoint(url="messages/flags", method="POST", request=update_data)
909916

917+
def _mark_as_read_using_narrow(self, narrow: List[Dict[str, Any]]) -> Dict[str, Any]:
918+
"""
919+
Helper method to batch mark messages as read using a narrow.
920+
This prevents server-side timeouts when marking a large number of messages
921+
as read (fixes Issue #820) by paginating through unread messages.
922+
"""
923+
request: Dict[str, Any] = {
924+
"anchor": "first_unread",
925+
"num_before": 0,
926+
"num_after": 1000,
927+
"narrow": narrow,
928+
"op": "add",
929+
"flag": "read",
930+
}
931+
res: Dict[str, Any] = {}
932+
while True:
933+
res = self.update_message_flags_for_narrow(request)
934+
if res.get("result") != "success":
935+
return res
936+
if res.get("found_newest", True):
937+
break
938+
if res.get("last_processed_id") is None:
939+
break
940+
request["anchor"] = res["last_processed_id"]
941+
return {"result": "success", "msg": "", "complete": True}
942+
910943
def mark_all_as_read(self) -> Dict[str, Any]:
911944
"""
912945
Example usage:
913946
914947
>>> client.mark_all_as_read()
915948
{'result': 'success', 'msg': ''}
916949
"""
950+
warnings.warn(
951+
"`mark_all_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
952+
DeprecationWarning,
953+
stacklevel=2,
954+
)
955+
if self.feature_level >= 155:
956+
return self._mark_as_read_using_narrow([{"operator": "is", "operand": "unread"}])
957+
917958
return self.call_endpoint(
918959
url="mark_all_as_read",
919960
method="POST",
@@ -926,6 +967,19 @@ def mark_stream_as_read(self, stream_id: int) -> Dict[str, Any]:
926967
>>> client.mark_stream_as_read(42)
927968
{'result': 'success', 'msg': ''}
928969
"""
970+
warnings.warn(
971+
"`mark_stream_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
972+
DeprecationWarning,
973+
stacklevel=2,
974+
)
975+
if self.feature_level >= 155:
976+
return self._mark_as_read_using_narrow(
977+
[
978+
{"operator": "stream", "operand": stream_id},
979+
{"operator": "is", "operand": "unread"},
980+
]
981+
)
982+
929983
return self.call_endpoint(
930984
url="mark_stream_as_read",
931985
method="POST",
@@ -936,9 +990,23 @@ def mark_topic_as_read(self, stream_id: int, topic_name: str) -> Dict[str, Any]:
936990
"""
937991
Example usage:
938992
939-
>>> client.mark_all_as_read(42, 'new coffee machine')
993+
>>> client.mark_topic_as_read(42, 'new coffee machine')
940994
{'result': 'success', 'msg': ''}
941995
"""
996+
warnings.warn(
997+
"`mark_topic_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
998+
DeprecationWarning,
999+
stacklevel=2,
1000+
)
1001+
if self.feature_level >= 155:
1002+
return self._mark_as_read_using_narrow(
1003+
[
1004+
{"operator": "stream", "operand": stream_id},
1005+
{"operator": "topic", "operand": topic_name},
1006+
{"operator": "is", "operand": "unread"},
1007+
]
1008+
)
1009+
9421010
return self.call_endpoint(
9431011
url="mark_topic_as_read",
9441012
method="POST",

0 commit comments

Comments
 (0)