Skip to content

Commit c644826

Browse files
showelltimabbott
authored andcommitted
refactor: Add MentionBackend.
We will eventually use this to avoid redundant queries. The diff is slightly noisy here, but there are no logic changes.
1 parent a22f49b commit c644826

File tree

7 files changed

+64
-38
lines changed

7 files changed

+64
-38
lines changed

zerver/lib/actions.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
from zerver.lib.i18n import get_language_name
101101
from zerver.lib.markdown import MessageRenderingResult, topic_links
102102
from zerver.lib.markdown import version as markdown_version
103-
from zerver.lib.mention import MentionData, silent_mention_syntax_for_user
103+
from zerver.lib.mention import MentionBackend, MentionData, silent_mention_syntax_for_user
104104
from zerver.lib.message import (
105105
MessageDict,
106106
SendMessageRequest,
@@ -1863,8 +1863,9 @@ def build_message_send_dict(
18631863
if realm is None:
18641864
realm = message.sender.realm
18651865

1866+
mention_backend = MentionBackend(realm.id)
18661867
mention_data = MentionData(
1867-
realm_id=realm.id,
1868+
mention_backend=mention_backend,
18681869
content=message.content,
18691870
)
18701871

@@ -3065,8 +3066,9 @@ def check_update_message(
30653066
content = "(deleted)"
30663067
content = normalize_body(content)
30673068

3069+
mention_backend = MentionBackend(user_profile.realm_id)
30683070
mention_data = MentionData(
3069-
realm_id=user_profile.realm.id,
3071+
mention_backend=mention_backend,
30703072
content=content,
30713073
)
30723074
user_info = get_user_info_for_message_updates(message.id)

zerver/lib/markdown/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
from zerver.lib.exceptions import MarkdownRenderingException
5555
from zerver.lib.markdown import fenced_code
5656
from zerver.lib.markdown.fenced_code import FENCE_RE
57-
from zerver.lib.mention import FullNameInfo, MentionData, get_stream_name_map
57+
from zerver.lib.mention import FullNameInfo, MentionBackend, MentionData, get_stream_name_map
5858
from zerver.lib.outgoing_http import OutgoingSession
5959
from zerver.lib.subdomains import is_static_or_current_realm_url
6060
from zerver.lib.tex import render_tex
@@ -2508,7 +2508,8 @@ def do_convert(
25082508
# are uncommon enough that it's a useful optimization.
25092509

25102510
if mention_data is None:
2511-
mention_data = MentionData(message_realm.id, content)
2511+
mention_backend = MentionBackend(message_realm.id)
2512+
mention_data = MentionData(mention_backend, content)
25122513

25132514
stream_names = possible_linked_stream_names(content)
25142515
stream_name_info = get_stream_name_map(message_realm, stream_names)

zerver/lib/mention.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,29 @@ def Q(self) -> Q:
3737
raise AssertionError("totally empty filter makes no sense")
3838

3939

40+
@dataclass
41+
class MentionBackend:
42+
realm_id: int
43+
44+
def get_full_name_info_list(self, user_filters: List[UserFilter]) -> List[FullNameInfo]:
45+
q_list = [user_filter.Q() for user_filter in user_filters]
46+
47+
rows = (
48+
UserProfile.objects.filter(
49+
realm_id=self.realm_id,
50+
is_active=True,
51+
)
52+
.filter(
53+
functools.reduce(lambda a, b: a | b, q_list),
54+
)
55+
.only(
56+
"id",
57+
"full_name",
58+
)
59+
)
60+
return [FullNameInfo(id=row.id, full_name=row.full_name) for row in rows]
61+
62+
4063
def user_mention_matches_wildcard(mention: str) -> bool:
4164
return mention in wildcards
4265

@@ -65,7 +88,9 @@ def possible_user_group_mentions(content: str) -> Set[str]:
6588
return {m.group("match") for m in USER_GROUP_MENTIONS_RE.finditer(content)}
6689

6790

68-
def get_possible_mentions_info(realm_id: int, mention_texts: Set[str]) -> List[FullNameInfo]:
91+
def get_possible_mentions_info(
92+
mention_backend: MentionBackend, mention_texts: Set[str]
93+
) -> List[FullNameInfo]:
6994
if not mention_texts:
7095
return []
7196

@@ -88,28 +113,14 @@ def get_possible_mentions_info(realm_id: int, mention_texts: Set[str]) -> List[F
88113
# For **name** syntax.
89114
user_filters.append(UserFilter(full_name=mention_text, id=None))
90115

91-
q_list = [user_filter.Q() for user_filter in user_filters]
92-
93-
rows = (
94-
UserProfile.objects.filter(
95-
realm_id=realm_id,
96-
is_active=True,
97-
)
98-
.filter(
99-
functools.reduce(lambda a, b: a | b, q_list),
100-
)
101-
.only(
102-
"id",
103-
"full_name",
104-
)
105-
)
106-
return [FullNameInfo(id=row.id, full_name=row.full_name) for row in rows]
116+
return mention_backend.get_full_name_info_list(user_filters)
107117

108118

109119
class MentionData:
110-
def __init__(self, realm_id: int, content: str) -> None:
120+
def __init__(self, mention_backend: MentionBackend, content: str) -> None:
121+
realm_id = mention_backend.realm_id
111122
mention_texts, has_wildcards = possible_mentions(content)
112-
possible_mentions_info = get_possible_mentions_info(realm_id, mention_texts)
123+
possible_mentions_info = get_possible_mentions_info(mention_backend, mention_texts)
113124
self.full_name_info = {row.full_name.lower(): row for row in possible_mentions_info}
114125
self.user_id_info = {row.id: row for row in possible_mentions_info}
115126
self.init_user_group_data(realm_id=realm_id, content=content)

zerver/tests/test_events.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
fetch_initial_state_data,
172172
post_process_state,
173173
)
174-
from zerver.lib.mention import MentionData
174+
from zerver.lib.mention import MentionBackend, MentionData
175175
from zerver.lib.message import render_markdown
176176
from zerver.lib.test_classes import ZulipTestCase
177177
from zerver.lib.test_helpers import (
@@ -437,8 +437,9 @@ def test_pm_send_message_events(self) -> None:
437437
content = "new content"
438438
rendering_result = render_markdown(pm, content)
439439
prior_mention_user_ids: Set[int] = set()
440+
mention_backend = MentionBackend(self.user_profile.realm_id)
440441
mention_data = MentionData(
441-
realm_id=self.user_profile.realm_id,
442+
mention_backend=mention_backend,
442443
content=content,
443444
)
444445

@@ -496,8 +497,9 @@ def test_stream_send_message_events(self) -> None:
496497
content = "new content"
497498
rendering_result = render_markdown(message, content)
498499
prior_mention_user_ids: Set[int] = set()
500+
mention_backend = MentionBackend(self.user_profile.realm_id)
499501
mention_data = MentionData(
500-
realm_id=self.user_profile.realm_id,
502+
mention_backend=mention_backend,
501503
content=content,
502504
)
503505

zerver/tests/test_markdown.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from zerver.lib.mdiff import diff_strings
4343
from zerver.lib.mention import (
4444
FullNameInfo,
45+
MentionBackend,
4546
MentionData,
4647
get_possible_mentions_info,
4748
possible_mentions,
@@ -232,8 +233,9 @@ def make_user(email: str, full_name: str) -> UserProfile:
232233

233234
fred4 = make_user("[email protected]", "Fred Flintstone")
234235

236+
mention_backend = MentionBackend(realm.id)
235237
lst = get_possible_mentions_info(
236-
realm.id, {"Fred Flintstone", "Cordelia, LEAR's daughter", "Not A User"}
238+
mention_backend, {"Fred Flintstone", "Cordelia, LEAR's daughter", "Not A User"}
237239
)
238240
set_of_names = set(map(lambda x: x.full_name.lower(), lst))
239241
self.assertEqual(set_of_names, {"fred flintstone", "cordelia, lear's daughter"})
@@ -259,7 +261,8 @@ def test_mention_data(self) -> None:
259261
hamlet = self.example_user("hamlet")
260262
cordelia = self.example_user("cordelia")
261263
content = "@**King Hamlet** @**Cordelia, lear's daughter**"
262-
mention_data = MentionData(realm.id, content)
264+
mention_backend = MentionBackend(realm.id)
265+
mention_data = MentionData(mention_backend, content)
263266
self.assertEqual(mention_data.get_user_ids(), {hamlet.id, cordelia.id})
264267
self.assertEqual(
265268
mention_data.get_user_by_id(hamlet.id),
@@ -275,7 +278,7 @@ def test_mention_data(self) -> None:
275278

276279
self.assertFalse(mention_data.message_has_wildcards())
277280
content = "@**King Hamlet** @**Cordelia, lear's daughter** @**all**"
278-
mention_data = MentionData(realm.id, content)
281+
mention_data = MentionData(mention_backend, content)
279282
self.assertTrue(mention_data.message_has_wildcards())
280283

281284
def test_invalid_katex_path(self) -> None:

zerver/tests/test_message_fetch.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
)
2222
from zerver.lib.avatar import avatar_url
2323
from zerver.lib.exceptions import JsonableError
24-
from zerver.lib.mention import MentionData
24+
from zerver.lib.mention import MentionBackend, MentionData
2525
from zerver.lib.message import (
2626
MessageDict,
2727
get_first_visible_message_id,
@@ -3776,7 +3776,8 @@ def update_message(self, msg: Message, content: str) -> None:
37763776
hamlet = self.example_user("hamlet")
37773777
realm_id = hamlet.realm.id
37783778
rendering_result = render_markdown(msg, content)
3779-
mention_data = MentionData(realm_id, content)
3779+
mention_backend = MentionBackend(realm_id)
3780+
mention_data = MentionData(mention_backend, content)
37803781
do_update_message(
37813782
hamlet,
37823783
msg,

zerver/tests/test_notification_data.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from zerver.lib.mention import MentionData
1+
from zerver.lib.mention import MentionBackend, MentionData
22
from zerver.lib.notification_data import get_user_group_mentions_data
33
from zerver.lib.test_classes import ZulipTestCase
44
from zerver.lib.user_groups import create_user_group
@@ -220,19 +220,21 @@ def test_user_group_mentions_map(self) -> None:
220220
hamlet_only = create_user_group("hamlet_only", [hamlet], realm)
221221
hamlet_and_cordelia = create_user_group("hamlet_and_cordelia", [hamlet, cordelia], realm)
222222

223+
mention_backend = MentionBackend(realm.id)
224+
223225
# Base case. No user/user group mentions
224226
result = get_user_group_mentions_data(
225227
mentioned_user_ids=set(),
226228
mentioned_user_group_ids=[],
227-
mention_data=MentionData(realm.id, "no group mentioned"),
229+
mention_data=MentionData(mention_backend, "no group mentioned"),
228230
)
229231
self.assertDictEqual(result, {})
230232

231233
# Only user group mentions, no personal mentions
232234
result = get_user_group_mentions_data(
233235
mentioned_user_ids=set(),
234236
mentioned_user_group_ids=[hamlet_and_cordelia.id],
235-
mention_data=MentionData(realm.id, "hey @*hamlet_and_cordelia*!"),
237+
mention_data=MentionData(mention_backend, "hey @*hamlet_and_cordelia*!"),
236238
)
237239
self.assertDictEqual(
238240
result,
@@ -247,7 +249,9 @@ def test_user_group_mentions_map(self) -> None:
247249
result = get_user_group_mentions_data(
248250
mentioned_user_ids=set(),
249251
mentioned_user_group_ids=[hamlet_and_cordelia.id, hamlet_only.id],
250-
mention_data=MentionData(realm.id, "hey @*hamlet_and_cordelia* and @*hamlet_only*"),
252+
mention_data=MentionData(
253+
mention_backend, "hey @*hamlet_and_cordelia* and @*hamlet_only*"
254+
),
251255
)
252256
self.assertDictEqual(
253257
result,
@@ -262,7 +266,9 @@ def test_user_group_mentions_map(self) -> None:
262266
result = get_user_group_mentions_data(
263267
mentioned_user_ids=set(),
264268
mentioned_user_group_ids=[hamlet_only.id, hamlet_and_cordelia.id],
265-
mention_data=MentionData(realm.id, "hey @*hamlet_only* and @*hamlet_and_cordelia*"),
269+
mention_data=MentionData(
270+
mention_backend, "hey @*hamlet_only* and @*hamlet_and_cordelia*"
271+
),
266272
)
267273
self.assertDictEqual(
268274
result,
@@ -277,7 +283,7 @@ def test_user_group_mentions_map(self) -> None:
277283
result = get_user_group_mentions_data(
278284
mentioned_user_ids={hamlet.id},
279285
mentioned_user_group_ids=[hamlet_and_cordelia.id],
280-
mention_data=MentionData(realm.id, "hey @*hamlet_and_cordelia*!"),
286+
mention_data=MentionData(mention_backend, "hey @*hamlet_and_cordelia*!"),
281287
)
282288
self.assertDictEqual(
283289
result,

0 commit comments

Comments
 (0)