-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DO NOT MERGE] add an option to use display names in chatrooms #28
base: olm-command
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,7 @@ | |
from .utils import ( | ||
server_ts_to_weechat, | ||
shorten_sender, | ||
underscore_nonalnum, | ||
string_strikethrough, | ||
color_pair, | ||
) | ||
|
@@ -124,18 +125,24 @@ def room_buffer_close_cb(server_name, buffer): | |
|
||
|
||
class WeechatUser(object): | ||
def __init__(self, nick, host=None, prefix="", join_time=None): | ||
def __init__(self, nick, host=None, prefix="", join_time=None, nick_ptr = None): | ||
# type: (str, str, str, int) -> None | ||
self.nick = nick | ||
self.host = host | ||
self.prefix = prefix | ||
self.color = W.info_get("nick_color_name", nick) | ||
# Use full user id here so weechat will color different user | ||
# with same display name using different colors | ||
self.color = W.info_get("nick_color_name", host if host else nick) | ||
self.join_time = join_time or time.time() | ||
self.speaking_time = None # type: Optional[int] | ||
self.nick_ptr = nick_ptr | ||
|
||
def update_speaking_time(self, new_time=None): | ||
self.speaking_time = new_time or time.time() | ||
|
||
def disambiguate_nick(self): | ||
return "{nick} ({host})".format(nick=self.nick, host=self.host) | ||
|
||
@property | ||
def joined_recently(self): | ||
# TODO make the delay configurable | ||
|
@@ -227,6 +234,7 @@ class WeechatChannelBuffer(object): | |
"kick": [SCRIPT_NAME + "_kick", "log4"], | ||
"invite": [SCRIPT_NAME + "_invite", "log4"], | ||
"topic": [SCRIPT_NAME + "_topic", "log3"], | ||
"change": [SCRIPT_NAME + "_nick", "log4"], | ||
} | ||
|
||
membership_messages = { | ||
|
@@ -347,6 +355,7 @@ def __init__(self, name, server_name, user): | |
|
||
self.name = "" | ||
self.users = {} # type: Dict[str, WeechatUser] | ||
self.duplicate_nicks = {} # type: Dict[str, List[WeechatUser]] | ||
self.smart_filtered_nicks = set() # type: Set[str] | ||
|
||
self.topic_author = "" | ||
|
@@ -491,13 +500,13 @@ def _message_tags(self, user, message_type): | |
|
||
return tags | ||
|
||
def _get_user(self, nick): | ||
def _get_user(self, user_id): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The WeechatChannelBuffer class was supposed to be protocol agnostic, that is it should not know what an user id is. If we are going to introduce user ids into the WeechatChannelBuffer class then the separation between WeechatChannelBuffer and RoomBuffer doesn't make any sense anymore and they should be merged into a single class. Fyi, if you chose to leave the separation, the user_id -> nick mapping is handled in this hashmap https://github.com/poljar/weechat-matrix/blob/olm-command/matrix/buffer.py#L849 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you have any other such abstract separations in you code somewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is in config.py. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're going to merge the classes please separate this into separate commits to ease the reviewing. |
||
# type: (str) -> WeechatUser | ||
if nick in self.users: | ||
return self.users[nick] | ||
if user_id in self.users: | ||
return self.users[user_id] | ||
|
||
# A message from a non joined user | ||
return WeechatUser(nick) | ||
return WeechatUser(user_id) | ||
|
||
def _print_message(self, user, message, date, tags, extra_prefix=""): | ||
prefix_string = ( | ||
|
@@ -521,19 +530,20 @@ def _print_message(self, user, message, date, tags, extra_prefix=""): | |
|
||
self.print_date_tags(data, date, tags) | ||
|
||
def message(self, nick, message, date, extra_tags=None, extra_prefix=""): | ||
def message(self, user_id, message, date, extra_tags=None, extra_prefix=""): | ||
# type: (str, str, int, List[str], str) -> None | ||
user = self._get_user(nick) | ||
user = self._get_user(user_id) | ||
tags_type = "message_private" if self.type == "private" else "message" | ||
tags = self._message_tags(user, tags_type) + (extra_tags or []) | ||
self._print_message(user, message, date, tags, extra_prefix) | ||
|
||
user.update_speaking_time(date) | ||
self.unmask_smart_filtered_nick(nick) | ||
if user.host: | ||
self.unmask_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need to filter the user_id here, the spec disallows white-space, more info here. nio should take care of events that contain invalid user_ids. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i am more worried about other symbols, like '=' or '@'. Couldn't find in weechat docs if those are allowed so decided not to risk it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe they are fine since the IRC plugin tends to put host names into tags. Any UTF-8 string is fine but the tags get separated by a space, so that's why display names are problematic. |
||
|
||
def notice(self, nick, message, date, extra_tags=None, extra_prefix=""): | ||
def notice(self, user_id, message, date, extra_tags=None, extra_prefix=""): | ||
# type: (str, str, int, Optional[List[str]], str) -> None | ||
user = self._get_user(nick) | ||
user = self._get_user(user_id) | ||
user_prefix = ( | ||
"" | ||
if not user.prefix | ||
|
@@ -566,7 +576,8 @@ def notice(self, nick, message, date, extra_tags=None, extra_prefix=""): | |
self.print_date_tags(data, date, tags) | ||
|
||
user.update_speaking_time(date) | ||
self.unmask_smart_filtered_nick(nick) | ||
if user.host: | ||
self.unmask_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
|
||
def _format_action(self, user, message): | ||
nick_prefix = ( | ||
|
@@ -599,15 +610,16 @@ def _print_action(self, user, message, date, tags, extra_prefix=""): | |
|
||
self.print_date_tags(data, date, tags) | ||
|
||
def action(self, nick, message, date, extra_tags=None, extra_prefix=""): | ||
def action(self, user_id, message, date, extra_tags=None, extra_prefix=""): | ||
# type: (str, str, int, Optional[List[str]], str) -> None | ||
user = self._get_user(nick) | ||
user = self._get_user(user_id) | ||
tags_type = "action_private" if self.type == "private" else "action" | ||
tags = self._message_tags(user, tags_type) + (extra_tags or []) | ||
self._print_action(user, message, date, tags, extra_prefix) | ||
|
||
user.update_speaking_time(date) | ||
self.unmask_smart_filtered_nick(nick) | ||
if user.host: | ||
self.unmask_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
|
||
@staticmethod | ||
def _get_nicklist_group(user): | ||
|
@@ -640,22 +652,43 @@ def _get_prefix_color(prefix): | |
|
||
def _add_user_to_nicklist(self, user): | ||
# type: (WeechatUser) -> None | ||
nick_pointer = W.nicklist_search_nick(self._ptr, "", user.nick) | ||
if user.nick in self.duplicate_nicks: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The disambiguation algorithm works well, great work. Sadly we forgot a crucial feature about it, the room display name depends on user display names if the room is unnamed. Therefore the algorithm should go into nio, and weechat should ask nio when adding, removing, and changing nicks if there are conflicts. After a user is added, removed or a nick change is performed weechat needs to ask nio for the new room display name and set the buffers short_name property to that (it already does that to an extent). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do you want nio to handle disambiguation in full or just put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what you mean by full. Anything that is needed to calculate a disambiguated display name and the room name should go into nio. The client of course can pick and chose what it will display to the user. But the client should be able to ask nio for a disambiguated name. So weechat remembers what it has displayed (it already does that), upon a join/leave or display name change it checks if it would have a conflict and if so asks nio for the disambiguated names. The room name calculation is inside of nio, I don't see how room member name calculation is any higher or lower level than this. Especially since correct room name calculation depends on the room member names. If you want to mix and match what gets displayed please make it configurable, I have a feeling that people will have different opinions on that. So 3 modes I guess, what we currently have (user ids without the host part), full display names, and your mixed mode. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry if it wasn't so clear, by full I mean that nio should track collisions and return disambiguated name only in case when there is a clash in a single the room. I understand that for room names this is kinda required. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Frankly speaking if matrix-nio/matrix-nio#4 going to be merged current mode of using part of user_id without host for nicks would be inconsistent with automatic room names. Do you have a suggestion how to make automatic room names configurable in matrix-nio? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm missing something... Could you elaborate on why it would be inconsistent? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case if you have a chat with account with display name "Foo" and user id There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The room names are already inconsistent since they use the full user id and the nicklist the short/local part of the user id. That being said a function that uses user ids instead of display names for room name calculation can be added to nio and the old behavior can be preserved that way. Another function that gives a room name consisting of only the local part of the user id is fine as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gordon-quad me? what? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, github falsly triggered on part of matrix user id |
||
if len(self.duplicate_nicks[user.nick]) == 1: | ||
u2 = self.duplicate_nicks[user.nick][0] | ||
g2 = W.nicklist_search_group( | ||
self._ptr, "", self._get_nicklist_group(u2) | ||
) | ||
p2 = user.prefix if user.prefix else " " | ||
W.nicklist_remove_nick(self._ptr, u2.nick_ptr) | ||
u2.nick_ptr = W.nicklist_add_nick( | ||
self._ptr, | ||
g2, | ||
u2.disambiguate_nick(), | ||
u2.color, | ||
p2, | ||
self._get_prefix_color(u2.prefix), | ||
1, | ||
) | ||
|
||
if not nick_pointer: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you remove the conditional here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oops, will bring it back There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is not required in new commit since nick_ptrs and duplicate nicks handled in separately |
||
group = W.nicklist_search_group( | ||
self._ptr, "", self._get_nicklist_group(user) | ||
) | ||
prefix = user.prefix if user.prefix else " " | ||
W.nicklist_add_nick( | ||
self._ptr, | ||
group, | ||
user.nick, | ||
user.color, | ||
prefix, | ||
self._get_prefix_color(user.prefix), | ||
1, | ||
) | ||
nick = user.disambiguate_nick() | ||
self.duplicate_nicks[user.nick] += [user] | ||
else: | ||
nick = user.nick | ||
self.duplicate_nicks[user.nick] = [user] | ||
|
||
group = W.nicklist_search_group( | ||
self._ptr, "", self._get_nicklist_group(user) | ||
) | ||
prefix = user.prefix if user.prefix else " " | ||
user.nick_ptr = W.nicklist_add_nick( | ||
self._ptr, | ||
group, | ||
nick, | ||
user.color, | ||
prefix, | ||
self._get_prefix_color(user.prefix), | ||
1, | ||
) | ||
|
||
def _membership_message(self, user, message_type): | ||
# type: (WeechatUser, str) -> str | ||
|
@@ -685,10 +718,29 @@ def _membership_message(self, user, message_type): | |
|
||
return message | ||
|
||
def _nick_change_message(self, user, old_nick, new_nick): | ||
action_color = "purple" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Purple is not a valid weechat color, you can see the available colors with the |
||
prefix = "network" | ||
|
||
message = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't print out the disambiguated nicks which can lead to confusion when we have duplicates, maybe it'll make sense to always print out the user id alongside the first nick? Also if you want to color the message, please make it configurable. The irc nick change message uses the default color, I would stick to that as a default as well. |
||
"{prefix}{color}{old_nick}{ncolor}" | ||
"{action_color} is now known as " | ||
"{color}{new_nick}{ncolor}" | ||
).format( | ||
prefix=W.prefix(prefix), | ||
color=W.color(user.color), | ||
old_nick=old_nick, | ||
action_color=W.color(action_color), | ||
new_nick=new_nick, | ||
ncolor=W.color("reset") | ||
) | ||
|
||
return message | ||
|
||
def join(self, user, date, message=True, extra_tags=None): | ||
# type: (WeechatUser, int, Optional[bool], Optional[List[str]]) -> None | ||
self._add_user_to_nicklist(user) | ||
self.users[user.nick] = user | ||
self.users[user.host] = user | ||
|
||
if len(self.users) > 2: | ||
W.buffer_set(self._ptr, "localvar_set_type", "channel") | ||
|
@@ -701,26 +753,67 @@ def join(self, user, date, message=True, extra_tags=None): | |
tags.append(SCRIPT_NAME + "_smart_filter") | ||
|
||
self.print_date_tags(msg, date, tags) | ||
self.add_smart_filtered_nick(user.nick) | ||
if user.host: | ||
self.add_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
|
||
def change_nick(self, user_id, old_nick, new_nick, date, message=True, extra_tags=None): | ||
# type: (str, str, int, Optional[bool], Optional[List[str]]) -> None | ||
user = self._get_user(user_id) | ||
self._remove_user_from_nicklist(user) | ||
user.nick = new_nick | ||
self._add_user_to_nicklist(user) | ||
|
||
if message: | ||
tags = self._message_tags(user, "change") | ||
msg = self._nick_change_message(user, old_nick, new_nick) | ||
|
||
# TODO add a option to disable smart filters | ||
tags.append(SCRIPT_NAME + "_smart_filter") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The irc plugin adds two more tags for nick changes: irc_nick1 and irc_nick2. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting, so i guess i cannot use spaces or special symbols in tags there during irc_nick1_%s construction. Will those tags serve any purpose for weechat if I strip displayname of whitespace, unicode and/or special symbols? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right, display names can contain spaces. I guess we'll have to change the smart filter algorithm to just use the user_id, and put the user_id into the tags of every message. |
||
|
||
self.print_date_tags(msg, date, tags) | ||
|
||
def invite(self, nick, date, extra_tags=None): | ||
def set_own_nick(self, nick): | ||
W.buffer_set(self._ptr, "localvar_set_nick", nick) | ||
W.buffer_set(self._ptr, "highlight_words", nick) | ||
|
||
def invite(self, user_id, date, extra_tags=None): | ||
# type: (str, int, Optional[List[str]]) -> None | ||
user = self._get_user(nick) | ||
user = self._get_user(user_id) | ||
tags = self._message_tags(user, "invite") | ||
message = self._membership_message(user, "invite") | ||
self.print_date_tags(message, date, tags + (extra_tags or [])) | ||
|
||
def remove_user_from_nicklist(self, user): | ||
def _remove_user_from_nicklist(self, user): | ||
# type: (WeechatUser) -> None | ||
nick_pointer = W.nicklist_search_nick(self._ptr, "", user.nick) | ||
|
||
if nick_pointer: | ||
W.nicklist_remove_nick(self._ptr, nick_pointer) | ||
if user.nick_ptr: | ||
W.nicklist_remove_nick(self._ptr, user.nick_ptr) | ||
user.nick_ptr = None | ||
|
||
self.duplicate_nicks[user.nick].remove(user) | ||
|
||
if len(self.duplicate_nicks[user.nick]) == 0: | ||
self.duplicate_nicks.pop(user.nick) | ||
elif len(self.duplicate_nicks[user.nick]) == 1: | ||
u2 = self.duplicate_nicks[user.nick][0] | ||
g2 = W.nicklist_search_group( | ||
self._ptr, "", self._get_nicklist_group(u2) | ||
) | ||
p2 = user.prefix if user.prefix else " " | ||
W.nicklist_remove_nick(self._ptr, u2.nick_ptr) | ||
u2.nick_ptr = W.nicklist_add_nick( | ||
self._ptr, | ||
g2, | ||
u2.nick, | ||
u2.color, | ||
p2, | ||
self._get_prefix_color(u2.prefix), | ||
1, | ||
) | ||
|
||
def _leave(self, nick, date, message, leave_type, extra_tags=None): | ||
def _leave(self, user_id, date, message, leave_type, extra_tags=None): | ||
# type: (str, int, bool, str, List[str]) -> None | ||
user = self._get_user(nick) | ||
self.remove_user_from_nicklist(user) | ||
user = self._get_user(user_id) | ||
self._remove_user_from_nicklist(user) | ||
|
||
if len(self.users) <= 2: | ||
W.buffer_set(self._ptr, "localvar_set_type", "private") | ||
|
@@ -734,21 +827,22 @@ def _leave(self, nick, date, message, leave_type, extra_tags=None): | |
|
||
msg = self._membership_message(user, leave_type) | ||
self.print_date_tags(msg, date, tags + (extra_tags or [])) | ||
self.remove_smart_filtered_nick(user.nick) | ||
if user.host: | ||
self.remove_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
|
||
if user.nick in self.users: | ||
del self.users[user.nick] | ||
if user_id in self.users: | ||
del self.users[user_id] | ||
|
||
def part(self, nick, date, message=True, extra_tags=None): | ||
def part(self, user_id, date, message=True, extra_tags=None): | ||
# type: (str, int, bool, Optional[List[str]]) -> None | ||
self._leave(nick, date, message, "part", extra_tags) | ||
self._leave(user_id, date, message, "part", extra_tags) | ||
|
||
def kick(self, nick, date, message=True, extra_tags=None): | ||
def kick(self, user_id, date, message=True, extra_tags=None): | ||
# type: (str, int, bool, Optional[List[str]]) -> None | ||
self._leave(nick, date, message, "kick", extra_tags) | ||
self._leave(user_id, date, message, "kick", extra_tags) | ||
|
||
def _print_topic(self, nick, topic, date): | ||
user = self._get_user(nick) | ||
def _print_topic(self, user_id, topic, date): | ||
user = self._get_user(user_id) | ||
tags = self._message_tags(user, "topic") | ||
|
||
data = ( | ||
|
@@ -766,7 +860,8 @@ def _print_topic(self, nick, topic, date): | |
|
||
self.print_date_tags(data, date, tags) | ||
user.update_speaking_time(date) | ||
self.unmask_smart_filtered_nick(nick) | ||
if user.host: | ||
self.unmask_smart_filtered_nick(underscore_nonalnum(user.host)) | ||
|
||
@property | ||
def topic(self): | ||
|
@@ -776,21 +871,21 @@ def topic(self): | |
def topic(self, topic): | ||
W.buffer_set(self._ptr, "title", topic) | ||
|
||
def change_topic(self, nick, topic, date, message=True): | ||
def change_topic(self, user_id, topic, date, message=True): | ||
if message: | ||
self._print_topic(nick, topic, date) | ||
self._print_topic(user_id, topic, date) | ||
|
||
self.topic = topic | ||
self.topic_author = nick | ||
self.topic_author = user_id | ||
self.topic_date = date | ||
|
||
def self_message(self, nick, message, date, tags=None): | ||
user = self._get_user(nick) | ||
def self_message(self, user_id, message, date, tags=None): | ||
user = self._get_user(user_id) | ||
tags = self._message_tags(user, "self_message") + (tags or []) | ||
self._print_message(user, message, date, tags) | ||
|
||
def self_action(self, nick, message, date, tags=None): | ||
user = self._get_user(nick) | ||
def self_action(self, user_id, message, date, tags=None): | ||
user = self._get_user(user_id) | ||
tags = self._message_tags(user, "self_message") + (tags or []) | ||
tags.append(SCRIPT_NAME + "_action") | ||
self._print_action(user, message, date, tags) | ||
|
@@ -847,7 +942,18 @@ def __init__(self, room, server_name, prev_batch): | |
# This dict remembers the connection from a user_id to the name we | ||
# displayed in the buffer | ||
self.displayed_nicks = {} | ||
user = shorten_sender(self.room.own_user_id) | ||
short_name = shorten_sender(self.room.own_user_id) | ||
# TODO this user list does not contain own user id for newly joined | ||
# rooms so we need to fetch own display_name from server | ||
# It's going to be fixed by following "join" event. | ||
if self.room.own_user_id in self.room.users: | ||
display_name = self.room.users[self.room.own_user_id].display_name | ||
else: | ||
display_name = None | ||
if G.CONFIG.look.use_display_names and display_name: | ||
user = display_name | ||
else: | ||
user = short_name | ||
|
||
self.weechat_buffer = WeechatChannelBuffer( | ||
buffer_name, server_name, user | ||
|
@@ -1004,10 +1110,10 @@ def add_user(self, user_id, date, is_state, force_add=False): | |
elif user.user_id.startswith("@freenode_"): | ||
short_name = shorten_sender(user.user_id[9:]) | ||
|
||
# TODO make this configurable | ||
if not short_name or short_name in self.displayed_nicks.values(): | ||
# Use the full user id, but don't include the @ | ||
nick = user_id[1:] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could not quite wrap my head around this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Short name can be an empty string here if someone has a user id of the format "@:example.org", someone in Matrix HQ had such an user id. |
||
display_name = user.display_name | ||
|
||
if G.CONFIG.look.use_display_names and display_name: | ||
nick = display_name | ||
else: | ||
nick = short_name | ||
|
||
|
@@ -1020,6 +1126,16 @@ def add_user(self, user_id, date, is_state, force_add=False): | |
|
||
self.weechat_buffer.join(buffer_user, date, not is_state) | ||
|
||
def change_nick(self, user_id, prev_nick, new_nick, date, is_state): | ||
# There is no such user | ||
if not user_id in self.displayed_nicks: | ||
return | ||
|
||
if self.room.own_user_id == user_id: | ||
self.weechat_buffer.set_own_nick(new_nick) | ||
|
||
self.weechat_buffer.change_nick(user_id, prev_nick, new_nick, date, not is_state) | ||
|
||
def handle_membership_events(self, event, is_state): | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
|
||
|
@@ -1032,19 +1148,25 @@ def handle_membership_events(self, event, is_state): | |
|
||
self.add_user(event.state_key, date, is_state) | ||
else: | ||
# TODO print out profile changes | ||
if (G.CONFIG.look.use_display_names and | ||
event.prev_content and | ||
"displayname" in event.prev_content and | ||
"displayname" in event.content): | ||
prev_name = event.prev_content["displayname"] | ||
new_name = event.content["displayname"] | ||
if prev_name != new_name: | ||
self.change_nick(event.state_key, prev_name, new_name, date, is_state) | ||
return | ||
|
||
elif event.content["membership"] == "leave": | ||
if event.state_key in self.unhandled_users: | ||
self.unhandled_users.remove(event.state_key) | ||
return | ||
|
||
nick = self.find_nick(event.state_key) | ||
if event.sender == event.state_key: | ||
self.weechat_buffer.part(nick, date, not is_state) | ||
self.weechat_buffer.part(event.state_key, date, not is_state) | ||
else: | ||
self.weechat_buffer.kick(nick, date, not is_state) | ||
self.weechat_buffer.kick(event.state_key, date, not is_state) | ||
|
||
if event.state_key in self.displayed_nicks: | ||
del self.displayed_nicks[event.state_key] | ||
|
@@ -1135,7 +1257,6 @@ def already_redacted(tags): | |
line.tags = tags | ||
|
||
def _handle_redacted_message(self, event): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
tags = self.get_event_tags(event) | ||
tags.append(SCRIPT_NAME + "_redacted") | ||
|
@@ -1159,13 +1280,11 @@ def _handle_redacted_message(self, event): | |
reason=reason, | ||
) | ||
|
||
self.weechat_buffer.message(nick, data, date, tags) | ||
self.weechat_buffer.message(event.sender, data, date, tags) | ||
|
||
def _handle_topic(self, event, is_state): | ||
nick = self.find_nick(event.sender) | ||
|
||
self.weechat_buffer.change_topic( | ||
nick, | ||
event.sender, | ||
event.topic, | ||
server_ts_to_weechat(event.server_timestamp), | ||
not is_state, | ||
|
@@ -1187,16 +1306,14 @@ def get_event_tags(event): | |
def _handle_power_level(self, _): | ||
for user_id in self.room.power_levels.users: | ||
if user_id in self.displayed_nicks: | ||
nick = self.find_nick(user_id) | ||
|
||
user = self.weechat_buffer.users[nick] | ||
user = self.weechat_buffer.users[user_id] | ||
user.power_level = self.room.power_levels.get_user_level( | ||
user_id | ||
) | ||
|
||
# There is no way to change the group of a user without | ||
# removing him from the nicklist | ||
self.weechat_buffer.remove_user_from_nicklist(user) | ||
self.weechat_buffer._remove_user_from_nicklist(user) | ||
self.weechat_buffer._add_user_to_nicklist(user) | ||
|
||
def handle_state_event(self, event): | ||
|
@@ -1271,19 +1388,17 @@ def handle_timeline_event(self, event): | |
# Emotes are a subclass of RoomMessageText, so put them before the text | ||
# ones | ||
elif isinstance(event, RoomMessageEmote): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
|
||
extra_prefix = (self.warning_prefix if event.decrypted | ||
and not event.verified else "") | ||
|
||
self.weechat_buffer.action( | ||
nick, event.body, date, self.get_event_tags(event), | ||
event.sender, event.body, date, self.get_event_tags(event), | ||
extra_prefix | ||
) | ||
|
||
elif isinstance(event, RoomMessageText): | ||
nick = self.find_nick(event.sender) | ||
formatted = None | ||
|
||
if event.formatted_body: | ||
|
@@ -1296,22 +1411,20 @@ def handle_timeline_event(self, event): | |
|
||
date = server_ts_to_weechat(event.server_timestamp) | ||
self.weechat_buffer.message( | ||
nick, data, date, self.get_event_tags(event), extra_prefix | ||
event.sender, data, date, self.get_event_tags(event), extra_prefix | ||
) | ||
|
||
elif isinstance(event, RoomMessageNotice): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
extra_prefix = (self.warning_prefix if event.decrypted | ||
and not event.verified else "") | ||
|
||
self.weechat_buffer.notice( | ||
nick, event.body, date, self.get_event_tags(event), | ||
event.sender, event.body, date, self.get_event_tags(event), | ||
extra_prefix | ||
) | ||
|
||
elif isinstance(event, RoomMessageMedia): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
http_url = Api.mxc_to_http(event.url) | ||
url = http_url if http_url else event.url | ||
|
@@ -1323,11 +1436,10 @@ def handle_timeline_event(self, event): | |
and not event.verified else "") | ||
|
||
self.weechat_buffer.message( | ||
nick, data, date, self.get_event_tags(event), extra_prefix | ||
event.sender, data, date, self.get_event_tags(event), extra_prefix | ||
) | ||
|
||
elif isinstance(event, RoomEncryptedMedia): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
http_url = Api.encrypted_mxc_to_plumb( | ||
event.url, | ||
|
@@ -1348,18 +1460,17 @@ def handle_timeline_event(self, event): | |
and not event.verified else "") | ||
|
||
self.weechat_buffer.message( | ||
nick, data, date, self.get_event_tags(event), extra_prefix | ||
event.sender, data, date, self.get_event_tags(event), extra_prefix | ||
) | ||
|
||
elif isinstance(event, RoomMessageUnknown): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
data = ("Unknown message of type {t}").format(t=event.type) | ||
extra_prefix = (self.warning_prefix if event.decrypted | ||
and not event.verified else "") | ||
|
||
self.weechat_buffer.message( | ||
nick, data, date, self.get_event_tags(event), extra_prefix | ||
event.sender, data, date, self.get_event_tags(event), extra_prefix | ||
) | ||
|
||
elif isinstance(event, RedactionEvent): | ||
|
@@ -1380,7 +1491,6 @@ def handle_timeline_event(self, event): | |
self._handle_power_level(event) | ||
|
||
elif isinstance(event, MegolmEvent): | ||
nick = self.find_nick(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
|
||
data = ("{del_color}<{log_color}Unable to decrypt: " | ||
|
@@ -1391,7 +1501,7 @@ def handle_timeline_event(self, event): | |
ncolor=W.color("reset")) | ||
session_id_tag = SCRIPT_NAME + "_sessionid_" + event.session_id | ||
self.weechat_buffer.message( | ||
nick, | ||
event.sender, | ||
data, | ||
date, | ||
self.get_event_tags(event) + [session_id_tag] | ||
|
@@ -1409,27 +1519,25 @@ def handle_timeline_event(self, event): | |
|
||
def self_message(self, message): | ||
# type: (OwnMessage) -> None | ||
nick = self.find_nick(self.room.own_user_id) | ||
data = message.formatted_message.to_weechat() | ||
if message.event_id: | ||
tags = [SCRIPT_NAME + "_id_{}".format(message.event_id)] | ||
else: | ||
tags = [SCRIPT_NAME + "_uuid_{}".format(message.uuid)] | ||
date = message.age | ||
|
||
self.weechat_buffer.self_message(nick, data, date, tags) | ||
self.weechat_buffer.self_message(self.room.own_user_id, data, date, tags) | ||
|
||
def self_action(self, message): | ||
# type: (OwnMessage) -> None | ||
nick = self.find_nick(self.room.own_user_id) | ||
date = message.age | ||
if message.event_id: | ||
tags = [SCRIPT_NAME + "_id_{}".format(message.event_id)] | ||
else: | ||
tags = [SCRIPT_NAME + "_uuid_{}".format(message.uuid)] | ||
|
||
self.weechat_buffer.self_action( | ||
nick, message.formatted_message.to_weechat(), date, tags | ||
self.room.own_user_id, message.formatted_message.to_weechat(), date, tags | ||
) | ||
|
||
@staticmethod | ||
|
@@ -1463,8 +1571,7 @@ def mark_message_as_unsent(self, uuid, _): | |
def replace_printed_line_by_uuid(self, uuid, new_message): | ||
"""Replace already printed lines that are greyed out with real ones.""" | ||
if isinstance(new_message, OwnAction): | ||
displayed_nick = self.displayed_nicks[self.room.own_user_id] | ||
user = self.weechat_buffer._get_user(displayed_nick) | ||
user = self.weechat_buffer._get_user(self.room.own_user_id) | ||
data = self.weechat_buffer._format_action( | ||
user, | ||
new_message.formatted_message.to_weechat() | ||
|
@@ -1554,8 +1661,7 @@ def old_redacted(self, event): | |
) | ||
|
||
tags += self.get_event_tags(event) | ||
nick = self.find_nick(event.sender) | ||
user = self.weechat_buffer._get_user(nick) | ||
user = self.weechat_buffer._get_user(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
self.weechat_buffer._print_message(user, data, date, tags) | ||
|
||
|
@@ -1567,15 +1673,14 @@ def old_message(self, event): | |
"no_highlight", | ||
] | ||
tags += self.get_event_tags(event) | ||
nick = self.find_nick(event.sender) | ||
|
||
formatted = None | ||
|
||
if event.formatted_body: | ||
formatted = Formatted.from_html(event.formatted_body) | ||
|
||
data = formatted.to_weechat() if formatted else event.body | ||
user = self.weechat_buffer._get_user(nick) | ||
user = self.weechat_buffer._get_user(event.sender) | ||
date = server_ts_to_weechat(event.server_timestamp) | ||
self.weechat_buffer._print_message(user, data, date, tags) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use a defaultdict here, that way we can always use duplicate_nicks[nick].append().