Skip to content

Commit 23a5c18

Browse files
authored
Allow users to be mentioned via Python API (#235)
* allow users to be mentioned via Python API * fix mypy errors
1 parent 6729c4d commit 23a5c18

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

python/jupyterlab-chat/jupyterlab_chat/models.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Message:
3838
attachments: Optional[list[str]] = None
3939
""" The message attachments, a list of attachment ID """
4040

41-
mentions: Optional[list[str]] = field(default_factory=list)
41+
mentions: list[str] = field(default_factory=list)
4242
""" Users mentioned in the message """
4343

4444
raw_time: Optional[bool] = None
@@ -75,12 +75,15 @@ class NewMessage:
7575
class User(JupyterUser):
7676
""" Object representing a user """
7777

78-
mention_name: Optional[str] = None
79-
""" The string to use as mention in chat """
80-
8178
bot: Optional[bool] = None
8279
""" Boolean identifying if user is a bot """
8380

81+
@property
82+
def mention_name(self) -> str:
83+
name: str = self.display_name or self.name or self.username
84+
name = name.replace(" ", "-")
85+
return name
86+
8487

8588
@dataclass
8689
class Attachment:

python/jupyterlab-chat/jupyterlab_chat/tests/test_ychat.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
display_name="Test user 2"
2323
)
2424

25+
USER3 = User(
26+
username=str(uuid4()),
27+
name="Test user 3",
28+
display_name="Test user 3"
29+
)
2530

2631
def create_new_message(body="This is a test message") -> NewMessage:
2732
return NewMessage(
@@ -43,6 +48,11 @@ def test_add_user():
4348
assert USER.username in chat._get_users().keys()
4449
assert chat._get_users()[USER.username] == asdict(USER)
4550

51+
def test_mention_names():
52+
assert USER.mention_name == "Test-user"
53+
assert USER2.mention_name == "Test-user-2"
54+
assert USER3.mention_name == "Test-user-3"
55+
4656

4757
def test_get_user_type():
4858
chat = YChat()
@@ -84,6 +94,22 @@ def test_add_message():
8494
assert message_dict["sender"] == msg.sender
8595

8696

97+
def test_add_message_includes_mentions():
98+
chat = YChat()
99+
chat.set_user(USER)
100+
chat.set_user(USER2)
101+
chat.set_user(USER3)
102+
103+
new_msg = create_new_message(
104+
f"@{USER2.mention_name} @{USER3.mention_name} Hello!"
105+
)
106+
msg_id = chat.add_message(new_msg)
107+
msg = chat.get_message(msg_id)
108+
assert msg
109+
110+
assert set(msg.mentions) == set([USER2.username, USER3.username])
111+
112+
87113
def test_get_message_should_return_the_message():
88114
chat = YChat()
89115
msg = create_new_message()

python/jupyterlab-chat/jupyterlab_chat/ychat.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import Any, Callable, Optional, Set
1313
from uuid import uuid4
1414
from pycrdt import Array, ArrayEvent, Map, MapEvent
15+
import re
1516

1617
from .models import message_asdict_factory, Attachment, Message, NewMessage, User
1718

@@ -132,9 +133,19 @@ def add_message(self, new_message: NewMessage) -> str:
132133
message = Message(
133134
**asdict(new_message),
134135
time=timestamp,
135-
id=uid
136+
id=uid,
136137
)
137138

139+
# find all mentioned users and add them as message mentions
140+
mention_pattern = re.compile("@([\w-]+):?")
141+
mentioned_names: Set[str] = set(re.findall(mention_pattern, message.body))
142+
users = self.get_users()
143+
mentioned_usernames = []
144+
for username, user in users.items():
145+
if user.mention_name in mentioned_names and user.username not in mentioned_usernames:
146+
mentioned_usernames.append(username)
147+
message.mentions = mentioned_usernames
148+
138149
with self._ydoc.transaction():
139150
index = len(self._ymessages) - next((i for i, v in enumerate(self._get_messages()[::-1]) if v["time"] < timestamp), len(self._ymessages))
140151
self._ymessages.insert(

0 commit comments

Comments
 (0)