Skip to content

Commit fdcd726

Browse files
committed
proper support of global and per-room display names
1 parent 7f821d6 commit fdcd726

File tree

3 files changed

+80
-11
lines changed

3 files changed

+80
-11
lines changed

matrix_client/room.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ def __init__(self, client, room_id):
4646
self.guest_access = None
4747
self._prev_batch = None
4848
self._members = {}
49+
self.members_displaynames = {
50+
# user_id: displayname
51+
}
4952
self.encrypted = False
5053

5154
def set_user_profile(self,
@@ -83,7 +86,7 @@ def display_name(self):
8386
return self.canonical_alias
8487

8588
# Member display names without me
86-
members = [u.get_display_name() for u in self.get_joined_members() if
89+
members = [u.get_display_name(self) for u in self.get_joined_members() if
8790
self.client.user_id != u.user_id]
8891
members.sort()
8992

@@ -478,10 +481,12 @@ def get_joined_members(self):
478481
response = self.client.api.get_room_members(self.room_id)
479482
for event in response["chunk"]:
480483
if event["content"]["membership"] == "join":
481-
self._add_member(event["state_key"], event["content"].get("displayname"))
484+
user_id = event["state_key"]
485+
self._add_member(user_id, event["content"].get("displayname"))
482486
return list(self._members.values())
483487

484488
def _add_member(self, user_id, displayname=None):
489+
self.members_displaynames[user_id] = displayname
485490
if user_id in self._members:
486491
return
487492
if user_id in self.client.users:
@@ -655,8 +660,8 @@ def _process_state_event(self, state_event):
655660
elif etype == "m.room.member" and clevel == clevel.ALL:
656661
# tracking room members can be large e.g. #matrix:matrix.org
657662
if econtent["membership"] == "join":
658-
self._add_member(
659-
state_event["state_key"], econtent.get("displayname"))
663+
user_id = state_event["state_key"]
664+
self._add_member(user_id, econtent.get("displayname"))
660665
elif econtent["membership"] in ("leave", "kick", "invite"):
661666
self._members.pop(state_event["state_key"], None)
662667

matrix_client/user.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15+
from warnings import warn
16+
1517
from .checks import check_user_id
1618

1719

@@ -25,20 +27,30 @@ def __init__(self, api, user_id, displayname=None):
2527
self.displayname = displayname
2628
self.api = api
2729

28-
def get_display_name(self):
29-
""" Get this users display name.
30-
See also get_friendly_name()
30+
def get_display_name(self, room=None):
31+
"""Get this user's display name.
32+
33+
Args:
34+
room (Room): Optional. When specified, return the display name of the user
35+
in this room.
3136
3237
Returns:
33-
str: Display Name
38+
The display name. Defaults to the user ID if not set.
3439
"""
40+
if room:
41+
try:
42+
return room.members_displaynames[self.user_id]
43+
except KeyError:
44+
return self.user_id
3545
if not self.displayname:
3646
self.displayname = self.api.get_display_name(self.user_id)
37-
return self.displayname
47+
return self.displayname or self.user_id
3848

3949
def get_friendly_name(self):
40-
display_name = self.api.get_display_name(self.user_id)
41-
return display_name if display_name is not None else self.user_id
50+
"""Deprecated. Use :meth:`get_display_name` instead."""
51+
warn("get_friendly_name is deprecated. Use get_display_name instead.",
52+
DeprecationWarning)
53+
return self.get_display_name()
4254

4355
def set_display_name(self, display_name):
4456
""" Set this users display name.

test/user_test.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import pytest
2+
import responses
3+
4+
from matrix_client.api import MATRIX_V2_API_PATH
5+
from matrix_client.client import MatrixClient
6+
from matrix_client.user import User
7+
8+
HOSTNAME = "http://localhost"
9+
10+
11+
class TestUser:
12+
cli = MatrixClient(HOSTNAME)
13+
user_id = "@test:localhost"
14+
room_id = "!test:localhost"
15+
16+
@pytest.fixture()
17+
def user(self):
18+
return User(self.cli.api, self.user_id)
19+
20+
@pytest.fixture()
21+
def room(self):
22+
return self.cli._mkroom(self.room_id)
23+
24+
@responses.activate
25+
def test_get_display_name(self, user, room):
26+
displayname_url = HOSTNAME + MATRIX_V2_API_PATH + \
27+
"/profile/{}/displayname".format(user.user_id)
28+
displayname = 'test'
29+
room_displayname = 'room_test'
30+
31+
# No displayname
32+
assert user.get_display_name(room) == user.user_id
33+
responses.add(responses.GET, displayname_url, json={})
34+
assert user.get_display_name() == user.user_id
35+
assert len(responses.calls) == 1
36+
37+
# Get global displayname
38+
responses.replace(responses.GET, displayname_url,
39+
json={"displayname": displayname})
40+
assert user.get_display_name() == displayname
41+
assert len(responses.calls) == 2
42+
43+
# Global displayname already present
44+
assert user.get_display_name() == displayname
45+
# No new request
46+
assert len(responses.calls) == 2
47+
48+
# Per-room displayname
49+
room.members_displaynames[user.user_id] = room_displayname
50+
assert user.get_display_name(room) == room_displayname
51+
# No new request
52+
assert len(responses.calls) == 2

0 commit comments

Comments
 (0)