buffer: Add a matrix specific buffer class.
This commit is contained in:
parent
ae5f97ce1d
commit
66507b23ce
3 changed files with 415 additions and 241 deletions
398
matrix/buffer.py
398
matrix/buffer.py
|
@ -18,11 +18,29 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
from builtins import super
|
||||
from functools import partial
|
||||
|
||||
from .globals import W, SERVERS, SCRIPT_NAME
|
||||
from .globals import W, SERVERS, OPTIONS, SCRIPT_NAME
|
||||
from .utf import utf8_decode
|
||||
from .colors import Formatted
|
||||
from builtins import super
|
||||
from .utils import shorten_sender, server_ts_to_weechat, string_strikethrough
|
||||
from .plugin_options import RedactType
|
||||
|
||||
|
||||
from .rooms import (
|
||||
RoomNameEvent,
|
||||
RoomAliasEvent,
|
||||
RoomMembershipEvent,
|
||||
RoomMemberJoin,
|
||||
RoomMemberLeave,
|
||||
RoomMemberInvite,
|
||||
RoomTopicEvent,
|
||||
RoomMessageText,
|
||||
RoomMessageEmote,
|
||||
RoomRedactionEvent,
|
||||
RoomRedactedMessageEvent
|
||||
)
|
||||
|
||||
|
||||
@utf8_decode
|
||||
|
@ -91,6 +109,12 @@ class WeechatChannelBuffer(object):
|
|||
"self_msg",
|
||||
"log1"
|
||||
],
|
||||
"action": [
|
||||
SCRIPT_NAME + "_message",
|
||||
SCRIPT_NAME + "_action",
|
||||
"notify_message",
|
||||
"log1",
|
||||
],
|
||||
"old_message": [
|
||||
SCRIPT_NAME + "_message",
|
||||
"notify_message",
|
||||
|
@ -126,6 +150,91 @@ class WeechatChannelBuffer(object):
|
|||
"invite": "has been invited to"
|
||||
}
|
||||
|
||||
class Line(object):
|
||||
def __init__(self, pointer):
|
||||
self._ptr = pointer
|
||||
|
||||
@property
|
||||
def _hdata(self):
|
||||
return W.hdata_get("line_data")
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return W.hdata_string(self._hdata, self._ptr, "prefix")
|
||||
|
||||
@prefix.setter
|
||||
def prefix(self, new_prefix):
|
||||
new_data = {"prefix": new_prefix}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
@property
|
||||
def message(self):
|
||||
return W.hdata_string(self._hdata, self._ptr, "message")
|
||||
|
||||
@message.setter
|
||||
def message(self, new_message):
|
||||
# type: (str) -> None
|
||||
new_data = {"message": new_message}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
tags_count = W.hdata_get_var_array_size(
|
||||
self._hdata,
|
||||
self._ptr,
|
||||
"tags_array"
|
||||
)
|
||||
|
||||
tags = [
|
||||
W.hdata_string(self._hdata, self._ptr, "%d|tags_array" % i)
|
||||
for i in range(tags_count)
|
||||
]
|
||||
return tags
|
||||
|
||||
@tags.setter
|
||||
def tags(self, new_tags):
|
||||
# type: (List[str]) -> None
|
||||
new_data = {"tags_array": ",".join(new_tags)}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
@property
|
||||
def date(self):
|
||||
# type: () -> int
|
||||
return W.hdata_time(self._hdata, self._ptr, "date")
|
||||
|
||||
@date.setter
|
||||
def date(self, new_date):
|
||||
# type: (int) -> None
|
||||
new_data = {"date": new_date}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
@property
|
||||
def date_printed(self):
|
||||
# type: () -> int
|
||||
return W.hdata_time(self._hdata, self._ptr, "date_printed")
|
||||
|
||||
@date_printed.setter
|
||||
def date_printed(self, new_date):
|
||||
# type: (int) -> None
|
||||
new_data = {"date_printed": new_date}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
@property
|
||||
def highlight(self):
|
||||
# type: () -> bool
|
||||
return bool(W.hdata_char(self._hdata, self._ptr, "highlight"))
|
||||
|
||||
def update(self, date, date_printed, tags, prefix, message):
|
||||
new_data = {
|
||||
"date": date,
|
||||
"date_printed": date_printed,
|
||||
"tags_array": ','.join(tags),
|
||||
"prefix": prefix,
|
||||
"message": message,
|
||||
# "highlight": highlight
|
||||
}
|
||||
W.hdata_update(self._hdata, self._ptr, new_data)
|
||||
|
||||
def __init__(self, name, server_name, user):
|
||||
# type: (str, str, str)
|
||||
self._ptr = W.buffer_new(
|
||||
|
@ -186,6 +295,8 @@ class WeechatChannelBuffer(object):
|
|||
W.buffer_set(self._ptr, "nicklist", "1")
|
||||
W.buffer_set(self._ptr, "nicklist_display_groups", "0")
|
||||
|
||||
W.buffer_set(self._ptr, "highlight_words", user)
|
||||
|
||||
# TODO make this configurable
|
||||
W.buffer_set(
|
||||
self._ptr,
|
||||
|
@ -193,6 +304,36 @@ class WeechatChannelBuffer(object):
|
|||
SCRIPT_NAME + "_message"
|
||||
)
|
||||
|
||||
@property
|
||||
def _hdata(self):
|
||||
return W.hdata_get("buffer")
|
||||
|
||||
@property
|
||||
def lines(self):
|
||||
own_lines = W.hdata_pointer(
|
||||
self._hdata,
|
||||
self._ptr,
|
||||
"own_lines"
|
||||
)
|
||||
|
||||
if own_lines:
|
||||
hdata_line = W.hdata_get("line")
|
||||
|
||||
line_pointer = W.hdata_pointer(
|
||||
W.hdata_get("lines"), own_lines, "last_line")
|
||||
|
||||
while line_pointer:
|
||||
data_pointer = W.hdata_pointer(
|
||||
hdata_line,
|
||||
line_pointer,
|
||||
"data"
|
||||
)
|
||||
|
||||
if data_pointer:
|
||||
yield WeechatChannelBuffer.Line(data_pointer)
|
||||
|
||||
line_pointer = W.hdata_move(hdata_line, line_pointer, -1)
|
||||
|
||||
def _print(self, string):
|
||||
# type: (str) -> None
|
||||
""" Print a string to the room buffer """
|
||||
|
@ -247,11 +388,7 @@ class WeechatChannelBuffer(object):
|
|||
# A message from a non joined user
|
||||
return RoomUser(nick)
|
||||
|
||||
def message(self, nick, message, date, tags=[]):
|
||||
# type: (str, str, int, str) -> None
|
||||
user = self._get_user(nick)
|
||||
tags = tags or self._message_tags(user, "message")
|
||||
|
||||
def _print_message(self, user, message, date, tags):
|
||||
prefix_string = ("" if not user.prefix else "{}{}{}".format(
|
||||
W.color(self._get_prefix_color(user.prefix)),
|
||||
user.prefix,
|
||||
|
@ -267,6 +404,12 @@ class WeechatChannelBuffer(object):
|
|||
|
||||
self.print_date_tags(data, date, tags)
|
||||
|
||||
def message(self, nick, message, date, extra_tags=[]):
|
||||
# type: (str, str, int, str) -> None
|
||||
user = self._get_user(nick)
|
||||
tags = self._message_tags(user, "message") + extra_tags
|
||||
self._print_message(user, message, date, tags)
|
||||
|
||||
def notice(self, nick, message, date):
|
||||
# type: (str, str, int) -> None
|
||||
data = "{color}{message}{ncolor}".format(
|
||||
|
@ -276,11 +419,7 @@ class WeechatChannelBuffer(object):
|
|||
|
||||
self.message(nick, data, date)
|
||||
|
||||
def action(self, nick, message, date, tags=[]):
|
||||
# type: (str, str, int) -> None
|
||||
user = self._get_user(nick)
|
||||
tags = tags or self._message_tags(user, "action")
|
||||
|
||||
def _print_action(self, user, message, date, tags):
|
||||
nick_prefix = ("" if not user.prefix else "{}{}{}".format(
|
||||
W.color(self._get_prefix_color(user.prefix)),
|
||||
user.prefix,
|
||||
|
@ -292,12 +431,18 @@ class WeechatChannelBuffer(object):
|
|||
prefix=W.prefix("action"),
|
||||
nick_prefix=nick_prefix,
|
||||
nick_color=W.color(user.color),
|
||||
author=nick,
|
||||
author=user.nick,
|
||||
ncolor=W.color("reset"),
|
||||
msg=message)
|
||||
|
||||
self.print_date_tags(data, date, tags)
|
||||
|
||||
def action(self, nick, message, date, extra_tags=[]):
|
||||
# type: (str, str, int) -> None
|
||||
user = self._get_user(nick)
|
||||
tags = self._message_tags(user, "action") + extra_tags
|
||||
self._print_action(user, message, date, tags)
|
||||
|
||||
@staticmethod
|
||||
def _get_nicklist_group(user):
|
||||
# type: (WeechatUser) -> str
|
||||
|
@ -456,13 +601,13 @@ class WeechatChannelBuffer(object):
|
|||
def self_message(self, nick, message, date):
|
||||
user = self._get_user(nick)
|
||||
tags = self._message_tags(user, "self_message")
|
||||
self.message(nick, message, date, tags)
|
||||
self._print_message(user, message, date, tags)
|
||||
|
||||
def self_action(self, nick, message, date):
|
||||
user = self._get_user(nick)
|
||||
tags = self._message_tags(user, "self_message")
|
||||
tags.append(SCRIPT_NAME + "_action")
|
||||
self.action(nick, message, date, tags)
|
||||
self._print_action(user, message, date, tags)
|
||||
|
||||
@property
|
||||
def short_name(self):
|
||||
|
@ -471,3 +616,226 @@ class WeechatChannelBuffer(object):
|
|||
@short_name.setter
|
||||
def short_name(self, name):
|
||||
W.buffer_set(self._ptr, "short_name", name)
|
||||
|
||||
def find_lines(self, predicate):
|
||||
lines = []
|
||||
for line in self.lines:
|
||||
if predicate(line):
|
||||
lines.append(line)
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
class RoomBuffer(object):
|
||||
def __init__(self, room, server_name):
|
||||
self.room = room
|
||||
user = shorten_sender(self.room.own_user_id)
|
||||
self.weechat_buffer = WeechatChannelBuffer(
|
||||
room.room_id,
|
||||
server_name,
|
||||
user
|
||||
)
|
||||
|
||||
def handle_membership_events(self, event, is_state):
|
||||
def join(event, date, is_state):
|
||||
user = self.room.users[event.sender]
|
||||
buffer_user = RoomUser(user.name, event.sender)
|
||||
# TODO remove this duplication
|
||||
user.nick_color = buffer_user.color
|
||||
|
||||
if self.room.own_user_id == event.sender:
|
||||
buffer_user.color = "weechat.color.chat_nick_self"
|
||||
user.nick_color = "weechat.color.chat_nick_self"
|
||||
|
||||
self.weechat_buffer.join(
|
||||
buffer_user,
|
||||
server_ts_to_weechat(event.timestamp),
|
||||
not is_state
|
||||
)
|
||||
|
||||
date = server_ts_to_weechat(event.timestamp)
|
||||
|
||||
if isinstance(event, RoomMemberJoin):
|
||||
if event.prev_content and "membership" in event.prev_content:
|
||||
if (event.prev_content["membership"] == "leave"
|
||||
or event.prev_content["membership"] == "invite"):
|
||||
join(event, date, is_state)
|
||||
else:
|
||||
# TODO print out profile changes
|
||||
return
|
||||
else:
|
||||
# No previous content for this user in this room, so he just
|
||||
# joined.
|
||||
join(event, date, is_state)
|
||||
|
||||
elif isinstance(event, RoomMemberLeave):
|
||||
# TODO the nick can be a display name or a full sender name
|
||||
nick = shorten_sender(event.sender)
|
||||
if event.sender == event.leaving_user:
|
||||
self.weechat_buffer.part(nick, date, not is_state)
|
||||
else:
|
||||
self.weechat_buffer.kick(nick, date, not is_state)
|
||||
|
||||
elif isinstance(event, RoomMemberInvite):
|
||||
if is_state:
|
||||
return
|
||||
|
||||
self.weechat_buffer.invite(event.invited_user, date)
|
||||
return
|
||||
|
||||
room_name = self.room.display_name(self.room.own_user_id)
|
||||
self.weechat_buffer.short_name = room_name
|
||||
|
||||
def _redact_line(self, event):
|
||||
def predicate(event_id, line):
|
||||
def already_redacted(tags):
|
||||
if SCRIPT_NAME + "_redacted" in tags:
|
||||
return True
|
||||
return False
|
||||
|
||||
event_tag = SCRIPT_NAME + "_id_{}".format(event_id)
|
||||
tags = line.tags
|
||||
|
||||
if event_tag in tags and not already_redacted(tags):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
lines = self.weechat_buffer.find_lines(
|
||||
partial(predicate, event.redaction_id)
|
||||
)
|
||||
|
||||
# No line to redact, return early
|
||||
if not lines:
|
||||
return
|
||||
|
||||
# TODO multiple lines can contain a single matrix ID, we need to redact
|
||||
# them all
|
||||
line = lines[0]
|
||||
|
||||
# TODO the censor may not be in the room anymore
|
||||
censor = self.room.users[event.sender].name
|
||||
message = line.message
|
||||
tags = line.tags
|
||||
|
||||
reason = ("" if not event.reason else
|
||||
", reason: \"{reason}\"".format(reason=event.reason))
|
||||
|
||||
redaction_msg = ("{del_color}<{log_color}Message redacted by: "
|
||||
"{censor}{log_color}{reason}{del_color}>"
|
||||
"{ncolor}").format(
|
||||
del_color=W.color("chat_delimiters"),
|
||||
ncolor=W.color("reset"),
|
||||
log_color=W.color("logger.color.backlog_line"),
|
||||
censor=censor,
|
||||
reason=reason)
|
||||
|
||||
new_message = ""
|
||||
|
||||
if OPTIONS.redaction_type == RedactType.STRIKETHROUGH:
|
||||
plaintext_msg = W.string_remove_color(message, '')
|
||||
new_message = string_strikethrough(plaintext_msg)
|
||||
elif OPTIONS.redaction_type == RedactType.NOTICE:
|
||||
new_message = message
|
||||
elif OPTIONS.redaction_type == RedactType.DELETE:
|
||||
pass
|
||||
|
||||
message = " ".join(s for s in [new_message, redaction_msg] if s)
|
||||
|
||||
tags.append("matrix_redacted")
|
||||
|
||||
line.message = message
|
||||
line.tags = tags
|
||||
|
||||
def _handle_redacted_message(self, event):
|
||||
# TODO user doesn't have to be in the room anymore
|
||||
user = self.room.users[event.sender]
|
||||
date = server_ts_to_weechat(event.timestamp)
|
||||
tags = self.get_event_tags(event)
|
||||
tags.append(SCRIPT_NAME + "_redacted")
|
||||
|
||||
reason = (", reason: \"{reason}\"".format(reason=event.reason)
|
||||
if event.reason else "")
|
||||
|
||||
censor = self.room.users[event.censor]
|
||||
|
||||
data = ("{del_color}<{log_color}Message redacted by: "
|
||||
"{censor}{log_color}{reason}{del_color}>{ncolor}").format(
|
||||
del_color=W.color("chat_delimiters"),
|
||||
ncolor=W.color("reset"),
|
||||
log_color=W.color("logger.color.backlog_line"),
|
||||
censor=censor.name,
|
||||
reason=reason)
|
||||
|
||||
self.weechat_buffer.message(user.name, data, date, tags)
|
||||
|
||||
def _handle_topic(self, event, is_state):
|
||||
try:
|
||||
user = self.room.users[event.sender]
|
||||
nick = user.name
|
||||
except KeyError:
|
||||
nick = event.sender
|
||||
|
||||
self.weechat_buffer.change_topic(
|
||||
nick,
|
||||
event.topic,
|
||||
server_ts_to_weechat(event.timestamp),
|
||||
not is_state)
|
||||
|
||||
@staticmethod
|
||||
def get_event_tags(event):
|
||||
return ["matrix_id_{}".format(event.event_id)]
|
||||
|
||||
def handle_state_event(self, event):
|
||||
if isinstance(event, RoomMembershipEvent):
|
||||
self.handle_membership_events(event, True)
|
||||
elif isinstance(event, RoomTopicEvent):
|
||||
self._handle_topic(event, True)
|
||||
|
||||
def handle_timeline_event(self, event):
|
||||
if isinstance(event, RoomMembershipEvent):
|
||||
self.handle_membership_events(event, False)
|
||||
elif isinstance(event, (RoomNameEvent, RoomAliasEvent)):
|
||||
room_name = self.room.display_name(self.room.own_user_id)
|
||||
self.weechat_buffer.short_name = room_name
|
||||
elif isinstance(event, RoomTopicEvent):
|
||||
self._handle_topic(event, False)
|
||||
elif isinstance(event, RoomMessageText):
|
||||
user = self.room.users[event.sender]
|
||||
data = (event.formatted_message.to_weechat()
|
||||
if event.formatted_message else event.message)
|
||||
|
||||
date = server_ts_to_weechat(event.timestamp)
|
||||
self.weechat_buffer.message(
|
||||
user.name,
|
||||
data,
|
||||
date,
|
||||
self.get_event_tags(event)
|
||||
)
|
||||
elif isinstance(event, RoomMessageEmote):
|
||||
user = self.room.users[event.sender]
|
||||
date = server_ts_to_weechat(event.timestamp)
|
||||
self.weechat_buffer.action(
|
||||
user.name,
|
||||
event.message,
|
||||
date,
|
||||
self.get_event_tags(event)
|
||||
)
|
||||
elif isinstance(event, RoomRedactionEvent):
|
||||
self._redact_line(event)
|
||||
elif isinstance(event, RoomRedactedMessageEvent):
|
||||
self._handle_redacted_message(event)
|
||||
|
||||
def self_message(self, message):
|
||||
user = self.room.users[self.room.own_user_id]
|
||||
data = (message.formatted_message.to_weechat()
|
||||
if message.formatted_message
|
||||
else message.message)
|
||||
|
||||
date = server_ts_to_weechat(message.timestamp)
|
||||
self.weechat_buffer.self_message(user.name, data, date)
|
||||
|
||||
def self_action(self, message):
|
||||
user = self.room.users[self.room.own_user_id]
|
||||
date = server_ts_to_weechat(message.timestamp)
|
||||
self.weechat_buffer.self_action(user.name, message.message, date)
|
||||
|
|
131
matrix/rooms.py
131
matrix/rooms.py
|
@ -40,10 +40,11 @@ PowerLevel = namedtuple('PowerLevel', ['user', 'level'])
|
|||
|
||||
class MatrixRoom:
|
||||
|
||||
def __init__(self, room_id):
|
||||
def __init__(self, room_id, own_user_id):
|
||||
# type: (str) -> None
|
||||
# yapf: disable
|
||||
self.room_id = room_id # type: str
|
||||
self.own_user_id = own_user_id
|
||||
self.canonical_alias = None # type: str
|
||||
self.name = None # type: str
|
||||
self.topic = "" # type: str
|
||||
|
@ -153,9 +154,23 @@ class MatrixRoom:
|
|||
short_name = shorten_sender(event.sender)
|
||||
user = MatrixUser(short_name, event.display_name)
|
||||
self.users[event.sender] = user
|
||||
return True
|
||||
|
||||
elif isinstance(event, RoomMemberLeave):
|
||||
if event.leaving_user in self.users:
|
||||
del self.users[event.leaving_user]
|
||||
return True
|
||||
|
||||
elif isinstance(event, RoomNameEvent):
|
||||
self.name = event.name
|
||||
|
||||
elif isinstance(event, RoomAliasEvent):
|
||||
self.canonical_alias = event.canonical_alias
|
||||
|
||||
elif isinstance(event, RoomEncryptionEvent):
|
||||
self.encrypted = True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class MatrixUser:
|
||||
|
@ -337,35 +352,6 @@ class RoomRedactedMessageEvent(RoomEvent):
|
|||
|
||||
return cls(event_id, sender, timestamp, censor, reason)
|
||||
|
||||
def execute(self, server, room, buff, tags):
|
||||
nick, color_name = sender_to_nick_and_color(room, self.sender)
|
||||
color = color_for_tags(color_name)
|
||||
date = server_ts_to_weechat(self.timestamp)
|
||||
|
||||
event_tags = add_event_tags(self.event_id, nick, color, tags)
|
||||
|
||||
reason = (", reason: \"{reason}\"".format(reason=self.reason)
|
||||
if self.reason else "")
|
||||
|
||||
censor, _ = sender_to_nick_and_color(room, self.censor)
|
||||
|
||||
msg = ("{del_color}<{log_color}Message redacted by: "
|
||||
"{censor}{log_color}{reason}{del_color}>{ncolor}").format(
|
||||
del_color=W.color("chat_delimiters"),
|
||||
ncolor=W.color("reset"),
|
||||
log_color=W.color("logger.color.backlog_line"),
|
||||
censor=censor,
|
||||
reason=reason)
|
||||
|
||||
event_tags.append("matrix_redacted")
|
||||
|
||||
tags_string = ",".join(event_tags)
|
||||
|
||||
data = "{author}\t{msg}".format(author=nick, msg=msg)
|
||||
|
||||
W.prnt_date_tags(buff, date, tags_string, data)
|
||||
|
||||
|
||||
class RoomMessageEvent(RoomEvent):
|
||||
|
||||
@classmethod
|
||||
|
@ -464,12 +450,6 @@ class RoomMessageText(RoomMessageEvent):
|
|||
|
||||
return cls(event_id, sender, timestamp, msg, formatted_msg)
|
||||
|
||||
def execute(self, server, room, buff, tags):
|
||||
msg = (self.formatted_message.to_weechat()
|
||||
if self.formatted_message else self.message)
|
||||
|
||||
self._print_message(msg, room, buff, tags)
|
||||
|
||||
|
||||
class RoomMessageEmote(RoomMessageSimple):
|
||||
|
||||
|
@ -688,60 +668,6 @@ class RoomRedactionEvent(RoomEvent):
|
|||
|
||||
return cls(event_id, sender, timestamp, redaction_id, reason)
|
||||
|
||||
@staticmethod
|
||||
def already_redacted(tags):
|
||||
if "matrix_redacted" in tags:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _redact_line(self, data_pointer, tags, room, buff):
|
||||
hdata_line_data = W.hdata_get('line_data')
|
||||
|
||||
message = W.hdata_string(hdata_line_data, data_pointer, 'message')
|
||||
censor, _ = sender_to_nick_and_color(room, self.sender)
|
||||
|
||||
reason = ("" if not self.reason else
|
||||
", reason: \"{reason}\"".format(reason=self.reason))
|
||||
|
||||
redaction_msg = ("{del_color}<{log_color}Message redacted by: "
|
||||
"{censor}{log_color}{reason}{del_color}>"
|
||||
"{ncolor}").format(
|
||||
del_color=W.color("chat_delimiters"),
|
||||
ncolor=W.color("reset"),
|
||||
log_color=W.color("logger.color.backlog_line"),
|
||||
censor=censor,
|
||||
reason=reason)
|
||||
|
||||
new_message = ""
|
||||
|
||||
if OPTIONS.redaction_type == RedactType.STRIKETHROUGH:
|
||||
plaintext_msg = W.string_remove_color(message, '')
|
||||
new_message = string_strikethrough(plaintext_msg)
|
||||
elif OPTIONS.redaction_type == RedactType.NOTICE:
|
||||
new_message = message
|
||||
elif OPTIONS.redaction_type == RedactType.DELETE:
|
||||
pass
|
||||
|
||||
message = " ".join(s for s in [new_message, redaction_msg] if s)
|
||||
|
||||
tags.append("matrix_redacted")
|
||||
|
||||
new_data = {'tags_array': ','.join(tags), 'message': message}
|
||||
|
||||
W.hdata_update(hdata_line_data, data_pointer, new_data)
|
||||
|
||||
def execute(self, server, room, buff, tags):
|
||||
data_pointer, tags = line_pointer_and_tags_from_event(
|
||||
buff, self.redaction_id)
|
||||
|
||||
if not data_pointer:
|
||||
return
|
||||
|
||||
if RoomRedactionEvent.already_redacted(tags):
|
||||
return
|
||||
|
||||
self._redact_line(data_pointer, tags, room, buff)
|
||||
|
||||
|
||||
class RoomNameEvent(RoomEvent):
|
||||
|
||||
|
@ -759,18 +685,6 @@ class RoomNameEvent(RoomEvent):
|
|||
|
||||
return cls(event_id, sender, timestamp, name)
|
||||
|
||||
def execute(self, server, room, buff, tags):
|
||||
if not self.name:
|
||||
return
|
||||
|
||||
room.name = self.name
|
||||
W.buffer_set(buff, "name", self.name)
|
||||
W.buffer_set(buff, "localvar_set_channel", self.name)
|
||||
|
||||
# calculate room display name and set it as the buffer list name
|
||||
room_name = room.display_name(server.user_id)
|
||||
W.buffer_set(buff, "short_name", room_name)
|
||||
|
||||
|
||||
class RoomAliasEvent(RoomEvent):
|
||||
|
||||
|
@ -788,19 +702,6 @@ class RoomAliasEvent(RoomEvent):
|
|||
|
||||
return cls(event_id, sender, timestamp, canonical_alias)
|
||||
|
||||
def execute(self, server, room, buff, tags):
|
||||
if not self.canonical_alias:
|
||||
return
|
||||
|
||||
# TODO: What should we do with this?
|
||||
# W.buffer_set(buff, "name", self.name)
|
||||
# W.buffer_set(buff, "localvar_set_channel", self.name)
|
||||
|
||||
# calculate room display name and set it as the buffer list name
|
||||
room.canonical_alias = self.canonical_alias
|
||||
room_name = room.display_name(server.user_id)
|
||||
W.buffer_set(buff, "short_name", room_name)
|
||||
|
||||
|
||||
class RoomEncryptionEvent(RoomEvent):
|
||||
|
||||
|
|
127
matrix/server.py
127
matrix/server.py
|
@ -34,7 +34,7 @@ from matrix.utils import (key_from_value, prnt_debug, server_buffer_prnt,
|
|||
from matrix.utf import utf8_decode
|
||||
from matrix.globals import W, SERVERS, OPTIONS
|
||||
import matrix.api as API
|
||||
from .buffer import WeechatChannelBuffer, RoomUser
|
||||
from .buffer import RoomBuffer
|
||||
from .rooms import (
|
||||
MatrixRoom,
|
||||
RoomMessageText,
|
||||
|
@ -633,101 +633,6 @@ class MatrixServer:
|
|||
server_buffer_prnt(self, pprint.pformat(message.request.payload))
|
||||
server_buffer_prnt(self, pprint.pformat(message.response.body))
|
||||
|
||||
def handle_room_membership_events(
|
||||
self,
|
||||
room,
|
||||
room_buffer,
|
||||
event,
|
||||
is_state_event
|
||||
):
|
||||
def join(event, date, room, room_buffer, is_state_event):
|
||||
user = room.users[event.sender]
|
||||
buffer_user = RoomUser(user.name, event.sender)
|
||||
# TODO remove this duplication
|
||||
user.nick_color = buffer_user.color
|
||||
|
||||
if self.user_id == event.sender:
|
||||
buffer_user.color = "weechat.color.chat_nick_self"
|
||||
user.nick_color = "weechat.color.chat_nick_self"
|
||||
|
||||
room_buffer.join(
|
||||
buffer_user,
|
||||
server_ts_to_weechat(event.timestamp),
|
||||
not is_state_event
|
||||
)
|
||||
|
||||
room.handle_event(event)
|
||||
date = server_ts_to_weechat(event.timestamp)
|
||||
|
||||
joined = False
|
||||
left = False
|
||||
|
||||
if isinstance(event, RoomMemberJoin):
|
||||
if event.prev_content and "membership" in event.prev_content:
|
||||
if (event.prev_content["membership"] == "leave"
|
||||
or event.prev_content["membership"] == "invite"):
|
||||
join(event, date, room, room_buffer, is_state_event)
|
||||
joined = True
|
||||
else:
|
||||
# TODO print out profile changes
|
||||
return
|
||||
else:
|
||||
# No previous content for this user in this room, so he just
|
||||
# joined.
|
||||
join(event, date, room, room_buffer, is_state_event)
|
||||
joined = True
|
||||
|
||||
elif isinstance(event, RoomMemberLeave):
|
||||
# TODO the nick can be a display name or a full sender name
|
||||
nick = shorten_sender(event.sender)
|
||||
if event.sender == event.leaving_user:
|
||||
room_buffer.part(nick, date, not is_state_event)
|
||||
else:
|
||||
room_buffer.kick(nick, date, not is_state_event)
|
||||
|
||||
left = True
|
||||
|
||||
elif isinstance(event, RoomMemberInvite):
|
||||
if is_state_event:
|
||||
return
|
||||
|
||||
room_buffer.invite(event.invited_user, date)
|
||||
return
|
||||
|
||||
# calculate room display name and set it as the buffer list name
|
||||
room_name = room.display_name(self.user_id)
|
||||
room_buffer.short_name = room_name
|
||||
|
||||
# A user has joined or left an encrypted room, we need to check for
|
||||
# new devices and create a new group session
|
||||
if room.encrypted and (joined or left):
|
||||
self.device_check_timestamp = None
|
||||
|
||||
def handle_room_event(self, room, room_buffer, event, is_state_event):
|
||||
if isinstance(event, RoomMembershipEvent):
|
||||
self.handle_room_membership_events(
|
||||
room,
|
||||
room_buffer,
|
||||
event,
|
||||
is_state_event
|
||||
)
|
||||
elif isinstance(event, RoomTopicEvent):
|
||||
try:
|
||||
user = room.users[event.sender]
|
||||
nick = user.name
|
||||
except KeyError:
|
||||
nick = event.sender
|
||||
|
||||
room_buffer.change_topic(
|
||||
nick,
|
||||
event.topic,
|
||||
server_ts_to_weechat(event.timestamp),
|
||||
not is_state_event
|
||||
)
|
||||
else:
|
||||
tags = tags_for_message("message")
|
||||
event.execute(self, room, room_buffer._ptr, tags)
|
||||
|
||||
def _loop_events(self, info, n):
|
||||
|
||||
for i in range(n+1):
|
||||
|
@ -742,7 +647,15 @@ class MatrixServer:
|
|||
return i
|
||||
|
||||
room, room_buffer = self.find_room_from_id(info.room_id)
|
||||
self.handle_room_event(room, room_buffer, event, is_state)
|
||||
# The room changed it's members, if the room is encrypted update
|
||||
# the device list
|
||||
if room.handle_event(event) and room.encrypted:
|
||||
self.device_check_timestamp = None
|
||||
|
||||
if is_state:
|
||||
room_buffer.handle_state_event(event)
|
||||
else:
|
||||
room_buffer.handle_timeline_event(event)
|
||||
|
||||
self.event_queue.appendleft(info)
|
||||
return i
|
||||
|
@ -777,18 +690,10 @@ class MatrixServer:
|
|||
|
||||
def handle_own_messages(self, room_buffer, message):
|
||||
if isinstance(message, RoomMessageText):
|
||||
msg = (message.formatted_message.to_weechat()
|
||||
if message.formatted_message
|
||||
else message.message)
|
||||
|
||||
date = server_ts_to_weechat(message.timestamp)
|
||||
room_buffer.self_message(self.user, msg, date)
|
||||
|
||||
room_buffer.self_message(message)
|
||||
return
|
||||
elif isinstance(message, RoomMessageEmote):
|
||||
date = server_ts_to_weechat(message.timestamp)
|
||||
room_buffer.self_action(self.user, message.message, date)
|
||||
|
||||
room_buffer.self_action(message)
|
||||
return
|
||||
|
||||
raise NotImplementedError("Unsupported message of type {}".format(
|
||||
|
@ -850,12 +755,12 @@ class MatrixServer:
|
|||
return
|
||||
|
||||
def create_room_buffer(self, room_id):
|
||||
buf = WeechatChannelBuffer(room_id, self.name, self.user)
|
||||
room = MatrixRoom(room_id, self.user_id)
|
||||
buf = RoomBuffer(room, self.name)
|
||||
# TODO this should turned into a propper class
|
||||
self.room_buffers[room_id] = buf
|
||||
self.buffers[room_id] = buf._ptr
|
||||
self.rooms[room_id] = MatrixRoom(room_id)
|
||||
pass
|
||||
self.buffers[room_id] = buf.weechat_buffer._ptr
|
||||
self.rooms[room_id] = room
|
||||
|
||||
def find_room_from_ptr(self, pointer):
|
||||
room_id = key_from_value(self.buffers, pointer)
|
||||
|
|
Loading…
Reference in a new issue