mirror of https://github.com/zulip/zulip.git
bugdown: Store if message has wildcards in MentionData.
We also switch the underlying exctact_mention_text method to use a regular for loop, as well as make the related methods return tuples of (names, is_wildcard). This abstraction is hidden from the MentionData callers behind mention_data.message_has_wildcards(). Concerns #13430.
This commit is contained in:
parent
fb9e2b68fd
commit
9174c636ce
|
@ -2114,7 +2114,7 @@ def get_possible_mentions_info(realm_id: int, mention_texts: Set[str]) -> List[F
|
||||||
|
|
||||||
class MentionData:
|
class MentionData:
|
||||||
def __init__(self, realm_id: int, content: str) -> None:
|
def __init__(self, realm_id: int, content: str) -> None:
|
||||||
mention_texts = possible_mentions(content)
|
mention_texts, has_wildcards = possible_mentions(content)
|
||||||
possible_mentions_info = get_possible_mentions_info(realm_id, mention_texts)
|
possible_mentions_info = get_possible_mentions_info(realm_id, mention_texts)
|
||||||
self.full_name_info = {
|
self.full_name_info = {
|
||||||
row['full_name'].lower(): row
|
row['full_name'].lower(): row
|
||||||
|
@ -2125,6 +2125,10 @@ class MentionData:
|
||||||
for row in possible_mentions_info
|
for row in possible_mentions_info
|
||||||
}
|
}
|
||||||
self.init_user_group_data(realm_id=realm_id, content=content)
|
self.init_user_group_data(realm_id=realm_id, content=content)
|
||||||
|
self.has_wildcards = has_wildcards
|
||||||
|
|
||||||
|
def message_has_wildcards(self) -> bool:
|
||||||
|
return self.has_wildcards
|
||||||
|
|
||||||
def init_user_group_data(self,
|
def init_user_group_data(self,
|
||||||
realm_id: int,
|
realm_id: int,
|
||||||
|
|
|
@ -12,25 +12,29 @@ wildcards = ['all', 'everyone', 'stream']
|
||||||
def user_mention_matches_wildcard(mention: str) -> bool:
|
def user_mention_matches_wildcard(mention: str) -> bool:
|
||||||
return mention in wildcards
|
return mention in wildcards
|
||||||
|
|
||||||
def extract_mention_text(m: Tuple[str, str]) -> Optional[str]:
|
def extract_mention_text(m: Tuple[str, str]) -> Tuple[Optional[str], bool]:
|
||||||
# re.findall provides tuples of match elements; we want the second
|
# re.findall provides tuples of match elements; we want the second
|
||||||
# to get the main mention content.
|
# to get the main mention content.
|
||||||
s = m[1]
|
s = m[1]
|
||||||
if s.startswith("**") and s.endswith("**"):
|
if s.startswith("**") and s.endswith("**"):
|
||||||
text = s[2:-2]
|
text = s[2:-2]
|
||||||
if text in wildcards:
|
if text in wildcards:
|
||||||
return None
|
return None, True
|
||||||
return text
|
return text, False
|
||||||
|
return None, False
|
||||||
|
|
||||||
# We don't care about @all, @everyone or @stream
|
def possible_mentions(content: str) -> Tuple[Set[str], bool]:
|
||||||
return None
|
|
||||||
|
|
||||||
def possible_mentions(content: str) -> Set[str]:
|
|
||||||
matches = re.findall(find_mentions, content)
|
matches = re.findall(find_mentions, content)
|
||||||
# mention texts can either be names, or an extended name|id syntax.
|
# mention texts can either be names, or an extended name|id syntax.
|
||||||
texts_with_none = (extract_mention_text(match) for match in matches)
|
texts = set()
|
||||||
texts = {text for text in texts_with_none if text}
|
message_has_wildcards = False
|
||||||
return texts
|
for match in matches:
|
||||||
|
text, is_wildcard = extract_mention_text(match)
|
||||||
|
if text:
|
||||||
|
texts.add(text)
|
||||||
|
if is_wildcard:
|
||||||
|
message_has_wildcards = True
|
||||||
|
return texts, message_has_wildcards
|
||||||
|
|
||||||
def extract_user_group(matched_text: str) -> str:
|
def extract_user_group(matched_text: str) -> str:
|
||||||
return matched_text[1:-1]
|
return matched_text[1:-1]
|
||||||
|
|
|
@ -242,6 +242,11 @@ class BugdownMiscTest(ZulipTestCase):
|
||||||
assert(user is not None)
|
assert(user is not None)
|
||||||
self.assertEqual(user['email'], hamlet.email)
|
self.assertEqual(user['email'], hamlet.email)
|
||||||
|
|
||||||
|
self.assertFalse(mention_data.message_has_wildcards())
|
||||||
|
content = '@**King Hamlet** @**Cordelia lear** @**all**'
|
||||||
|
mention_data = bugdown.MentionData(realm.id, content)
|
||||||
|
self.assertTrue(mention_data.message_has_wildcards())
|
||||||
|
|
||||||
def test_invalid_katex_path(self) -> None:
|
def test_invalid_katex_path(self) -> None:
|
||||||
with self.settings(DEPLOY_ROOT="/nonexistent"):
|
with self.settings(DEPLOY_ROOT="/nonexistent"):
|
||||||
with mock.patch('logging.error') as mock_logger:
|
with mock.patch('logging.error') as mock_logger:
|
||||||
|
@ -1344,17 +1349,17 @@ class BugdownTest(ZulipTestCase):
|
||||||
self.assertEqual(msg.mentions_user_ids, set())
|
self.assertEqual(msg.mentions_user_ids, set())
|
||||||
|
|
||||||
def test_possible_mentions(self) -> None:
|
def test_possible_mentions(self) -> None:
|
||||||
def assert_mentions(content: str, names: Set[str]) -> None:
|
def assert_mentions(content: str, names: Set[str], has_wildcards: Optional[bool]=False) -> None:
|
||||||
self.assertEqual(possible_mentions(content), names)
|
self.assertEqual(possible_mentions(content), (names, has_wildcards))
|
||||||
|
|
||||||
assert_mentions('', set())
|
assert_mentions('', set())
|
||||||
assert_mentions('boring', set())
|
assert_mentions('boring', set())
|
||||||
assert_mentions('@**all**', set())
|
assert_mentions('@**all**', set(), True)
|
||||||
assert_mentions('smush@**steve**smush', set())
|
assert_mentions('smush@**steve**smush', set())
|
||||||
|
|
||||||
assert_mentions(
|
assert_mentions(
|
||||||
'Hello @**King Hamlet** and @**Cordelia Lear**\n@**Foo van Barson|1234** @**all**',
|
'Hello @**King Hamlet** and @**Cordelia Lear**\n@**Foo van Barson|1234** @**all**',
|
||||||
{'King Hamlet', 'Cordelia Lear', 'Foo van Barson|1234'}
|
{'King Hamlet', 'Cordelia Lear', 'Foo van Barson|1234'}, True
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_mention_multiple(self) -> None:
|
def test_mention_multiple(self) -> None:
|
||||||
|
|
Loading…
Reference in New Issue