Skip to content

Commit 9a2f41c

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

1 file changed

Lines changed: 68 additions & 1 deletion

File tree

zulip/zulip/__init__.py

Lines changed: 68 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,58 @@ 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+
while True:
932+
res = self.update_message_flags_for_narrow(request)
933+
if res.get("result") != "success":
934+
return res
935+
if res.get("found_newest", True):
936+
break
937+
if res.get("last_processed_id") is None:
938+
break
939+
request["anchor"] = res["last_processed_id"]
940+
return {"result": "success", "msg": "", "complete": True}
941+
910942
def mark_all_as_read(self) -> Dict[str, Any]:
911943
"""
912944
Example usage:
913945
914946
>>> client.mark_all_as_read()
915947
{'result': 'success', 'msg': ''}
916948
"""
949+
warnings.warn(
950+
"`mark_all_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
951+
DeprecationWarning,
952+
stacklevel=2,
953+
)
954+
if self.feature_level >= 155:
955+
return self._mark_as_read_using_narrow([{"operator": "is", "operand": "unread"}])
956+
917957
return self.call_endpoint(
918958
url="mark_all_as_read",
919959
method="POST",
@@ -926,6 +966,19 @@ def mark_stream_as_read(self, stream_id: int) -> Dict[str, Any]:
926966
>>> client.mark_stream_as_read(42)
927967
{'result': 'success', 'msg': ''}
928968
"""
969+
warnings.warn(
970+
"`mark_stream_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
971+
DeprecationWarning,
972+
stacklevel=2,
973+
)
974+
if self.feature_level >= 155:
975+
return self._mark_as_read_using_narrow(
976+
[
977+
{"operator": "stream", "operand": stream_id},
978+
{"operator": "is", "operand": "unread"},
979+
]
980+
)
981+
929982
return self.call_endpoint(
930983
url="mark_stream_as_read",
931984
method="POST",
@@ -936,9 +989,23 @@ def mark_topic_as_read(self, stream_id: int, topic_name: str) -> Dict[str, Any]:
936989
"""
937990
Example usage:
938991
939-
>>> client.mark_all_as_read(42, 'new coffee machine')
992+
>>> client.mark_topic_as_read(42, 'new coffee machine')
940993
{'result': 'success', 'msg': ''}
941994
"""
995+
warnings.warn(
996+
"`mark_topic_as_read` is deprecated. Use `update_message_flags_for_narrow` instead.",
997+
DeprecationWarning,
998+
stacklevel=2,
999+
)
1000+
if self.feature_level >= 155:
1001+
return self._mark_as_read_using_narrow(
1002+
[
1003+
{"operator": "stream", "operand": stream_id},
1004+
{"operator": "topic", "operand": topic_name},
1005+
{"operator": "is", "operand": "unread"},
1006+
]
1007+
)
1008+
9421009
return self.call_endpoint(
9431010
url="mark_topic_as_read",
9441011
method="POST",

0 commit comments

Comments
 (0)