Add initial sync event implementation.

This commit is contained in:
poljar (Damir Jelić) 2018-02-22 13:39:37 +01:00
parent 9b25026a3a
commit 2ac8bef499
4 changed files with 282 additions and 244 deletions

View file

@ -289,6 +289,11 @@ class MatrixSyncMessage(MatrixMessage):
MatrixMessage.__init__(self, MessageType.SYNC, client.sync, data) MatrixMessage.__init__(self, MessageType.SYNC, client.sync, data)
def decode_body(self, server):
object_hook = partial(MatrixEvents.MatrixSyncEvent.from_dict, server)
return self._decode(server, object_hook)
class MatrixSendMessage(MatrixMessage): class MatrixSendMessage(MatrixMessage):
@ -448,19 +453,3 @@ class MatrixUser:
self.power_level = 0 # type: int self.power_level = 0 # type: int
self.nick_color = "" # type: str self.nick_color = "" # type: str
self.prefix = "" # type: str self.prefix = "" # type: str
class MatrixRoom:
def __init__(self, room_id):
# type: (str) -> None
# yapf: disable
self.room_id = room_id # type: str
self.alias = room_id # type: str
self.topic = "" # type: str
self.topic_author = "" # type: str
self.topic_date = None # type: datetime.datetime
self.prev_batch = "" # type: str
self.users = dict() # type: Dict[str, MatrixUser]
self.encrypted = False # type: bool
# yapf: enable

View file

@ -27,9 +27,10 @@ from matrix.utils import (
date_from_age, date_from_age,
sender_to_nick_and_color, sender_to_nick_and_color,
tags_for_message, tags_for_message,
add_event_tags add_event_tags,
) )
from matrix.colors import Formatted from matrix.colors import Formatted
from matrix.rooms import matrix_create_room_buffer
def sanitize_token(string): def sanitize_token(string):
@ -91,17 +92,13 @@ def sanitize_text(string):
if not isinstance(string, str): if not isinstance(string, str):
raise TypeError raise TypeError
remap = { remap = {ord('\b'): None, ord('\f'): None, ord('\r'): None, ord('\0'): None}
ord('\b'): None,
ord('\f'): None,
ord('\r'): None,
ord('\0'): None
}
return string.translate(remap) return string.translate(remap)
class MatrixEvent(): class MatrixEvent():
def __init__(self, server): def __init__(self, server):
self.server = server self.server = server
@ -110,6 +107,7 @@ class MatrixEvent():
class MatrixErrorEvent(MatrixEvent): class MatrixErrorEvent(MatrixEvent):
def __init__(self, server, error_message, fatal=False): def __init__(self, server, error_message, fatal=False):
self.error_message = error_message self.error_message = error_message
self.fatal = fatal self.fatal = fatal
@ -117,8 +115,7 @@ class MatrixErrorEvent(MatrixEvent):
def execute(self): def execute(self):
message = ("{prefix}matrix: {error}").format( message = ("{prefix}matrix: {error}").format(
prefix=W.prefix("error"), prefix=W.prefix("error"), error=self.error_message)
error=self.error_message)
W.prnt(self.server.server_buffer, message) W.prnt(self.server.server_buffer, message)
@ -129,22 +126,17 @@ class MatrixErrorEvent(MatrixEvent):
def from_dict(cls, server, error_prefix, fatal, parsed_dict): def from_dict(cls, server, error_prefix, fatal, parsed_dict):
try: try:
message = "{prefix}: {error}".format( message = "{prefix}: {error}".format(
prefix=error_prefix, prefix=error_prefix, error=parsed_dict["error"])
error=parsed_dict["error"]) return cls(server, message, fatal=fatal)
return cls(
server,
message,
fatal=fatal
)
except KeyError: except KeyError:
return cls( return cls(
server, server, ("{prefix}: Invalid JSON response "
("{prefix}: Invalid JSON response "
"from server.").format(prefix=error_prefix), "from server.").format(prefix=error_prefix),
fatal=fatal) fatal=fatal)
class MatrixLoginEvent(MatrixEvent): class MatrixLoginEvent(MatrixEvent):
def __init__(self, server, user_id, access_token): def __init__(self, server, user_id, access_token):
self.user_id = user_id self.user_id = user_id
self.access_token = access_token self.access_token = access_token
@ -160,21 +152,15 @@ class MatrixLoginEvent(MatrixEvent):
@classmethod @classmethod
def from_dict(cls, server, parsed_dict): def from_dict(cls, server, parsed_dict):
try: try:
return cls( return cls(server, sanitize_id(parsed_dict["user_id"]),
server, sanitize_token(parsed_dict["access_token"]))
sanitize_id(parsed_dict["user_id"]),
sanitize_token(parsed_dict["access_token"])
)
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error logging in", True,
server, parsed_dict)
"Error logging in",
True,
parsed_dict
)
class MatrixSendEvent(MatrixEvent): class MatrixSendEvent(MatrixEvent):
def __init__(self, server, room_id, event_id, message): def __init__(self, server, room_id, event_id, message):
self.room_id = room_id self.room_id = room_id
self.event_id = event_id self.event_id = event_id
@ -208,22 +194,15 @@ class MatrixSendEvent(MatrixEvent):
@classmethod @classmethod
def from_dict(cls, server, room_id, message, parsed_dict): def from_dict(cls, server, room_id, message, parsed_dict):
try: try:
return cls( return cls(server, room_id, sanitize_id(parsed_dict["event_id"]),
server, message)
room_id,
sanitize_id(parsed_dict["event_id"]),
message
)
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error sending message",
server, False, parsed_dict)
"Error sending message",
False,
parsed_dict
)
class MatrixTopicEvent(MatrixEvent): class MatrixTopicEvent(MatrixEvent):
def __init__(self, server, room_id, event_id, topic): def __init__(self, server, room_id, event_id, topic):
self.room_id = room_id self.room_id = room_id
self.topic = topic self.topic = topic
@ -233,22 +212,15 @@ class MatrixTopicEvent(MatrixEvent):
@classmethod @classmethod
def from_dict(cls, server, room_id, topic, parsed_dict): def from_dict(cls, server, room_id, topic, parsed_dict):
try: try:
return cls( return cls(server, room_id, sanitize_id(parsed_dict["event_id"]),
server, topic)
room_id,
sanitize_id(parsed_dict["event_id"]),
topic
)
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error setting topic",
server, False, parsed_dict)
"Error setting topic",
False,
parsed_dict
)
class MatrixRedactEvent(MatrixEvent): class MatrixRedactEvent(MatrixEvent):
def __init__(self, server, room_id, event_id, reason): def __init__(self, server, room_id, event_id, reason):
self.room_id = room_id self.room_id = room_id
self.topic = reason self.topic = reason
@ -258,22 +230,15 @@ class MatrixRedactEvent(MatrixEvent):
@classmethod @classmethod
def from_dict(cls, server, room_id, reason, parsed_dict): def from_dict(cls, server, room_id, reason, parsed_dict):
try: try:
return cls( return cls(server, room_id, sanitize_id(parsed_dict["event_id"]),
server, reason)
room_id,
sanitize_id(parsed_dict["event_id"]),
reason
)
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error redacting message",
server, False, parsed_dict)
"Error redacting message",
False,
parsed_dict
)
class MatrixJoinEvent(MatrixEvent): class MatrixJoinEvent(MatrixEvent):
def __init__(self, server, room, room_id): def __init__(self, server, room, room_id):
self.room = room self.room = room
self.room_id = room_id self.room_id = room_id
@ -288,15 +253,12 @@ class MatrixJoinEvent(MatrixEvent):
sanitize_id(parsed_dict["room_id"]), sanitize_id(parsed_dict["room_id"]),
) )
except (KeyError, TypeError, ValueError): except (KeyError, TypeError, ValueError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error joining room",
server, False, parsed_dict)
"Error joining room",
False,
parsed_dict
)
class MatrixPartEvent(MatrixEvent): class MatrixPartEvent(MatrixEvent):
def __init__(self, server, room_id): def __init__(self, server, room_id):
self.room_id = room_id self.room_id = room_id
MatrixEvent.__init__(self, server) MatrixEvent.__init__(self, server)
@ -305,21 +267,16 @@ class MatrixPartEvent(MatrixEvent):
def from_dict(cls, server, room_id, parsed_dict): def from_dict(cls, server, room_id, parsed_dict):
try: try:
if parsed_dict == {}: if parsed_dict == {}:
return cls( return cls(server, room_id)
server,
room_id)
raise KeyError raise KeyError
except KeyError: except KeyError:
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error leaving room",
server, False, parsed_dict)
"Error leaving room",
False,
parsed_dict
)
class MatrixInviteEvent(MatrixEvent): class MatrixInviteEvent(MatrixEvent):
def __init__(self, server, room_id, user_id): def __init__(self, server, room_id, user_id):
self.room_id = room_id self.room_id = room_id
self.user_id = user_id self.user_id = user_id
@ -329,22 +286,16 @@ class MatrixInviteEvent(MatrixEvent):
def from_dict(cls, server, room_id, user_id, parsed_dict): def from_dict(cls, server, room_id, user_id, parsed_dict):
try: try:
if parsed_dict == {}: if parsed_dict == {}:
return cls( return cls(server, room_id, user_id)
server,
room_id,
user_id)
raise KeyError raise KeyError
except KeyError: except KeyError:
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error inviting user",
server, False, parsed_dict)
"Error inviting user",
False,
parsed_dict
)
class MatrixBacklogEvent(MatrixEvent): class MatrixBacklogEvent(MatrixEvent):
def __init__(self, server, room_id, end_token, messages): def __init__(self, server, room_id, end_token, messages):
self.room_id = room_id self.room_id = room_id
self.end_token = end_token self.end_token = end_token
@ -369,30 +320,19 @@ class MatrixBacklogEvent(MatrixEvent):
end_token = sanitize_id(parsed_dict["end"]) end_token = sanitize_id(parsed_dict["end"])
message_func = partial( message_func = partial(MatrixBacklogEvent._message_from_event,
MatrixBacklogEvent._message_from_event, room_id)
room_id
)
message_events = list(filter( message_events = list(
lambda event: event["type"] == "m.room.message", filter(lambda event: event["type"] == "m.room.message",
parsed_dict["chunk"] parsed_dict["chunk"]))
))
messages = [message_func(m) for m in message_events] messages = [message_func(m) for m in message_events]
return cls( return cls(server, room_id, end_token, messages)
server,
room_id,
end_token,
messages)
except (KeyError, ValueError, TypeError): except (KeyError, ValueError, TypeError):
return MatrixErrorEvent.from_dict( return MatrixErrorEvent.from_dict(server, "Error fetching backlog",
server, False, parsed_dict)
"Error fetching backlog",
False,
parsed_dict
)
def execute(self): def execute(self):
room = self.server.rooms[self.room_id] room = self.server.rooms[self.room_id]
@ -405,7 +345,119 @@ class MatrixBacklogEvent(MatrixEvent):
room.prev_batch = self.end_token room.prev_batch = self.end_token
class MatrixSyncEvent(MatrixEvent):
def __init__(self, server, next_batch, room_infos, invited_infos):
self.next_batch = next_batch
self.joined_room_infos = room_infos
self.invited_room_infos = invited_infos
MatrixEvent.__init__(self, server)
@staticmethod
def _infos_from_dict(parsed_dict):
join_infos = []
invite_infos = []
for room_id, room_dict in parsed_dict['join'].items():
if not room_id:
continue
join_infos.append(RoomInfo.from_dict(room_id, room_dict))
return (join_infos, invite_infos)
@classmethod
def from_dict(cls, server, parsed_dict):
try:
next_batch = parsed_dict["next_batch"]
room_info_dict = parsed_dict["rooms"]
join_infos, invite_infos = MatrixSyncEvent._infos_from_dict(
room_info_dict)
return cls(server, next_batch, join_infos, invite_infos)
except (KeyError, ValueError, TypeError):
return MatrixErrorEvent.from_dict(server, "Error syncing", False,
parsed_dict)
def _execute_joined_info(self, info):
server = self.server
if info.room_id not in server.buffers:
matrix_create_room_buffer(server, info.room_id)
room = server.rooms[info.room_id]
buf = server.buffers[info.room_id]
if not room.prev_batch:
room.prev_batch = info.prev_batch
tags = tags_for_message("message")
for message in info.events:
message.prnt(room, buf, tags)
def execute(self):
server = self.server
# we got the same batch again, nothing to do
if self.next_batch == server.next_batch:
server.sync()
return
map(self._execute_joined_info, self.joined_room_infos)
server.next_batch = self.next_batch
server.sync()
class RoomInfo():
def __init__(self, room_id, prev_batch, events):
# type: (str, str, List[Any]) -> None
self.room_id = room_id
self.prev_batch = prev_batch
self.events = events
@staticmethod
def _message_from_event(event):
# The transaction id will only be present for events that are send out from
# this client, since we print out our own messages as soon as we get a
# receive confirmation from the server we don't care about our own messages
# in a sync event. More info under:
# https://github.com/matrix-org/matrix-doc/blob/master/api/client-server/definitions/event.yaml#L53
if "transaction_id" in event["unsigned"]:
return None
if "redacted_by" in event["unsigned"]:
return RedactedMessage.from_dict(event)
return Message.from_dict(event)
@staticmethod
def _event_from_dict(event):
if event['type'] == 'm.room.message':
return RoomInfo._message_from_event(event)
@classmethod
def from_dict(cls, room_id, parsed_dict):
prev_batch = sanitize_id(parsed_dict['timeline']['prev_batch'])
events = []
state_dict = parsed_dict['state']['events']
timeline_dict = parsed_dict['timeline']['events']
for event in timeline_dict:
events.append(RoomInfo._event_from_dict(event))
filtered_events = list(filter(None, events))
return cls(room_id, prev_batch, filtered_events)
class AbstractMessage(): class AbstractMessage():
def __init__(self, event_id, sender, age): def __init__(self, event_id, sender, age):
self.event_id = event_id self.event_id = event_id
self.sender = sender self.sender = sender
@ -413,6 +465,7 @@ class AbstractMessage():
class RedactedMessage(AbstractMessage): class RedactedMessage(AbstractMessage):
def __init__(self, event_id, sender, age, censor, reason=None): def __init__(self, event_id, sender, age, censor, reason=None):
self.censor = censor self.censor = censor
self.reason = reason self.reason = reason
@ -424,8 +477,7 @@ class RedactedMessage(AbstractMessage):
sender = sanitize_id(event["sender"]) sender = sanitize_id(event["sender"])
age = event["unsigned"]["age"] age = event["unsigned"]["age"]
censor = sanitize_id( censor = sanitize_id(event['unsigned']['redacted_because']['sender'])
event['unsigned']['redacted_because']['sender'])
reason = None reason = None
if 'reason' in event['unsigned']['redacted_because']['content']: if 'reason' in event['unsigned']['redacted_because']['content']:
@ -439,12 +491,7 @@ class RedactedMessage(AbstractMessage):
color = color_for_tags(color_name) color = color_for_tags(color_name)
date = date_from_age(self.age) date = date_from_age(self.age)
event_tags = add_event_tags( event_tags = add_event_tags(self.event_id, nick, color, tags)
self.event_id,
nick,
color,
tags
)
reason = (", reason: \"{reason}\"".format(reason=self.reason) reason = (", reason: \"{reason}\"".format(reason=self.reason)
if self.reason else "") if self.reason else "")
@ -469,14 +516,8 @@ class RedactedMessage(AbstractMessage):
class Message(AbstractMessage): class Message(AbstractMessage):
def __init__(
self, def __init__(self, event_id, sender, age, message, formatted_message=None):
event_id,
sender,
age,
message,
formatted_message=None
):
self.message = message self.message = message
self.formatted_message = formatted_message self.formatted_message = formatted_message
AbstractMessage.__init__(self, event_id, sender, age) AbstractMessage.__init__(self, event_id, sender, age)
@ -502,19 +543,13 @@ class Message(AbstractMessage):
return cls(event_id, sender, age, msg, formatted_msg) return cls(event_id, sender, age, msg, formatted_msg)
def prnt(self, room, buff, tags): def prnt(self, room, buff, tags):
msg = (self.formatted_message.to_weechat() if msg = (self.formatted_message.to_weechat()
self.formatted_message if self.formatted_message else self.message)
else self.message)
nick, color_name = sender_to_nick_and_color(room, self.sender) nick, color_name = sender_to_nick_and_color(room, self.sender)
color = color_for_tags(color_name) color = color_for_tags(color_name)
event_tags = add_event_tags( event_tags = add_event_tags(self.event_id, nick, color, tags)
self.event_id,
nick,
color,
tags
)
tags_string = ",".join(event_tags) tags_string = ",".join(event_tags)

View file

@ -28,18 +28,12 @@ from matrix.colors import Formatted
from matrix.globals import W, OPTIONS from matrix.globals import W, OPTIONS
from matrix.api import ( from matrix.api import (MessageType, MatrixUser)
MessageType,
MatrixRoom,
MatrixUser
)
from matrix.utils import ( from matrix.rooms import MatrixRoom
server_buffer_prnt,
tags_from_line_data, from matrix.utils import (server_buffer_prnt, tags_from_line_data, prnt_debug,
prnt_debug, color_for_tags)
color_for_tags
)
from matrix.plugin_options import RedactType, DebugType from matrix.plugin_options import RedactType, DebugType
@ -60,26 +54,14 @@ def add_user_to_nicklist(buf, user):
group = W.nicklist_search_group(buf, "", group_name) group = W.nicklist_search_group(buf, "", group_name)
# TODO make it configurable so we can use a display name or user_id here # TODO make it configurable so we can use a display name or user_id here
W.nicklist_add_nick( W.nicklist_add_nick(buf, group, user.display_name, user.nick_color,
buf, user.prefix, get_prefix_color(user.prefix), 1)
group,
user.display_name,
user.nick_color,
user.prefix,
get_prefix_color(user.prefix),
1
)
def matrix_create_room_buffer(server, room_id): def matrix_create_room_buffer(server, room_id):
# type: (MatrixServer, str) -> None # type: (MatrixServer, str) -> None
buf = W.buffer_new( buf = W.buffer_new(room_id, "room_input_cb", server.name, "room_close_cb",
room_id, server.name)
"room_input_cb",
server.name,
"room_close_cb",
server.name
)
W.buffer_set(buf, "localvar_set_type", 'channel') W.buffer_set(buf, "localvar_set_type", 'channel')
W.buffer_set(buf, "type", 'formatted') W.buffer_set(buf, "type", 'formatted')
@ -142,9 +124,7 @@ def matrix_handle_room_members(server, room_id, event):
if full_name == server.user_id: if full_name == server.user_id:
user.nick_color = "weechat.color.chat_nick_self" user.nick_color = "weechat.color.chat_nick_self"
W.buffer_set( W.buffer_set(buf, "highlight_words",
buf,
"highlight_words",
",".join([full_name, user.name, user.display_name])) ",".join([full_name, user.name, user.display_name]))
else: else:
user.nick_color = W.info_get("nick_color_name", user.name) user.nick_color = W.info_get("nick_color_name", user.name)
@ -346,8 +326,7 @@ def matrix_redact_line(data, tags, event):
tags.append("matrix_new_redacted") tags.append("matrix_new_redacted")
new_data = {'tags_array': ','.join(tags), new_data = {'tags_array': ','.join(tags), 'message': message}
'message': message}
W.hdata_update(hdata_line_data, data, new_data) W.hdata_update(hdata_line_data, data, new_data)
@ -363,11 +342,7 @@ def matrix_handle_room_redaction(server, room_id, event):
if own_lines: if own_lines:
hdata_line = W.hdata_get('line') hdata_line = W.hdata_get('line')
line = W.hdata_pointer( line = W.hdata_pointer(W.hdata_get('lines'), own_lines, 'last_line')
W.hdata_get('lines'),
own_lines,
'last_line'
)
while line: while line:
data = W.hdata_pointer(hdata_line, line, 'data') data = W.hdata_pointer(hdata_line, line, 'data')
@ -501,11 +476,11 @@ def matrix_handle_room_events(server, room_id, room_events):
matrix_handle_room_power_levels(server, room_id, event) matrix_handle_room_power_levels(server, room_id, event)
# These events are unimportant for us. # These events are unimportant for us.
elif event["type"] in ["m.room.create", "m.room.join_rules", elif event["type"] in [
"m.room.history_visibility", "m.room.create", "m.room.join_rules",
"m.room.canonical_alias", "m.room.history_visibility", "m.room.canonical_alias",
"m.room.guest_access", "m.room.guest_access", "m.room.third_party_invite"
"m.room.third_party_invite"]: ]:
pass pass
elif event["type"] == "m.room.name": elif event["type"] == "m.room.name":
@ -538,8 +513,7 @@ def matrix_handle_room_events(server, room_id, room_events):
else: else:
message = ("{prefix}Handling of room event type " message = ("{prefix}Handling of room event type "
"{type} not implemented").format( "{type} not implemented").format(
type=event['type'], type=event['type'], prefix=W.prefix("error"))
prefix=W.prefix("error"))
W.prnt(server.server_buffer, message) W.prnt(server.server_buffer, message)
@ -582,11 +556,8 @@ def matrix_handle_room_info(server, room_info):
matrix_handle_room_events(server, room_id, room['timeline']['events']) matrix_handle_room_events(server, room_id, room['timeline']['events'])
for room_id, room in room_info['invite'].items(): for room_id, room in room_info['invite'].items():
matrix_handle_invite_events( matrix_handle_invite_events(server, room_id,
server, room['invite_state']['events'])
room_id,
room['invite_state']['events']
)
def matrix_sort_old_messages(server, room_id): def matrix_sort_old_messages(server, room_id):
@ -598,11 +569,7 @@ def matrix_sort_old_messages(server, room_id):
if own_lines: if own_lines:
hdata_line = W.hdata_get('line') hdata_line = W.hdata_get('line')
hdata_line_data = W.hdata_get('line_data') hdata_line_data = W.hdata_get('line_data')
line = W.hdata_pointer( line = W.hdata_pointer(W.hdata_get('lines'), own_lines, 'first_line')
W.hdata_get('lines'),
own_lines,
'first_line'
)
while line: while line:
data = W.hdata_pointer(hdata_line, line, 'data') data = W.hdata_pointer(hdata_line, line, 'data')
@ -611,18 +578,18 @@ def matrix_sort_old_messages(server, room_id):
if data: if data:
date = W.hdata_time(hdata_line_data, data, 'date') date = W.hdata_time(hdata_line_data, data, 'date')
print_date = W.hdata_time(hdata_line_data, data, print_date = W.hdata_time(hdata_line_data, data, 'date_printed')
'date_printed')
tags = tags_from_line_data(data) tags = tags_from_line_data(data)
prefix = W.hdata_string(hdata_line_data, data, 'prefix') prefix = W.hdata_string(hdata_line_data, data, 'prefix')
message = W.hdata_string(hdata_line_data, data, message = W.hdata_string(hdata_line_data, data, 'message')
'message')
line_data = {'date': date, line_data = {
'date': date,
'date_printed': print_date, 'date_printed': print_date,
'tags_array': ','.join(tags), 'tags_array': ','.join(tags),
'prefix': prefix, 'prefix': prefix,
'message': message} 'message': message
}
lines.append(line_data) lines.append(line_data)
@ -645,11 +612,7 @@ def matrix_update_buffer_lines(new_lines, own_lines):
hdata_line = W.hdata_get('line') hdata_line = W.hdata_get('line')
hdata_line_data = W.hdata_get('line_data') hdata_line_data = W.hdata_get('line_data')
line = W.hdata_pointer( line = W.hdata_pointer(W.hdata_get('lines'), own_lines, 'first_line')
W.hdata_get('lines'),
own_lines,
'first_line'
)
while line: while line:
data = W.hdata_pointer(hdata_line, line, 'data') data = W.hdata_pointer(hdata_line, line, 'data')
@ -702,20 +665,8 @@ def matrix_handle_message(
matrix_sort_old_messages(server, message.room_id) matrix_sort_old_messages(server, message.room_id)
elif message_type is MessageType.SYNC: elif message_type is MessageType.SYNC:
next_batch = response['next_batch'] event = message.event
event.execute()
# we got the same batch again, nothing to do
if next_batch == server.next_batch:
server.sync()
return
room_info = response['rooms']
matrix_handle_room_info(server, room_info)
server.next_batch = next_batch
# TODO add a delay to this
server.sync()
else: else:
server_buffer_prnt( server_buffer_prnt(
@ -737,8 +688,7 @@ def handle_http_response(server, message):
# TODO try to resend the message if decoding has failed? # TODO try to resend the message if decoding has failed?
message = ("{prefix}matrix: Error decoding json response from " message = ("{prefix}matrix: Error decoding json response from "
"server: {error}").format( "server: {error}").format(
prefix=W.prefix("error"), prefix=W.prefix("error"), error=error)
error=error)
W.prnt(server.server_buffer, message) W.prnt(server.server_buffer, message)
return return
@ -805,11 +755,9 @@ def handle_http_response(server, message):
else: else:
server_buffer_prnt( server_buffer_prnt(
server, server, ("{prefix}Unhandled {status_code} error, please inform "
("{prefix}Unhandled {status_code} error, please inform "
"the developers about this.").format( "the developers about this.").format(
prefix=W.prefix("error"), prefix=W.prefix("error"), status_code=status_code))
status_code=status_code))
server_buffer_prnt(server, pprint.pformat(message.type)) server_buffer_prnt(server, pprint.pformat(message.type))
server_buffer_prnt(server, pprint.pformat(message.request.payload)) server_buffer_prnt(server, pprint.pformat(message.request.payload))
@ -828,7 +776,8 @@ def handle_http_response(server, message):
s=(message.send_time - message.creation_time) * 1000, s=(message.send_time - message.creation_time) * 1000,
r=(message.receive_time - message.send_time) * 1000, r=(message.receive_time - message.send_time) * 1000,
h=(done_time - message.receive_time) * 1000, h=(done_time - message.receive_time) * 1000,
total=(done_time - message.creation_time) * 1000,) total=(done_time - message.creation_time) * 1000,
)
prnt_debug(DebugType.TIMING, server, info_message) prnt_debug(DebugType.TIMING, server, info_message)
return return

65
matrix/rooms.py Normal file
View file

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
# Copyright © 2018 Damir Jelić <poljar@termina.org.uk>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals
from matrix.globals import W
from matrix.utils import strip_matrix_server
class MatrixRoom:
def __init__(self, room_id):
# type: (str) -> None
# yapf: disable
self.room_id = room_id # type: str
self.alias = room_id # type: str
self.topic = "" # type: str
self.topic_author = "" # type: str
self.topic_date = None # type: datetime.datetime
self.prev_batch = "" # type: str
self.users = dict() # type: Dict[str, MatrixUser]
self.encrypted = False # type: bool
# yapf: enable
def matrix_create_room_buffer(server, room_id):
# type: (MatrixServer, str) -> None
buf = W.buffer_new(room_id, "room_input_cb", server.name, "room_close_cb",
server.name)
W.buffer_set(buf, "localvar_set_type", 'channel')
W.buffer_set(buf, "type", 'formatted')
W.buffer_set(buf, "localvar_set_channel", room_id)
W.buffer_set(buf, "localvar_set_nick", server.user)
W.buffer_set(buf, "localvar_set_server", server.name)
short_name = strip_matrix_server(room_id)
W.buffer_set(buf, "short_name", short_name)
W.nicklist_add_group(buf, '', "000|o", "weechat.color.nicklist_group", 1)
W.nicklist_add_group(buf, '', "001|h", "weechat.color.nicklist_group", 1)
W.nicklist_add_group(buf, '', "002|v", "weechat.color.nicklist_group", 1)
W.nicklist_add_group(buf, '', "999|...", "weechat.color.nicklist_group", 1)
W.buffer_set(buf, "nicklist", "1")
W.buffer_set(buf, "nicklist_display_groups", "0")
server.buffers[room_id] = buf
server.rooms[room_id] = MatrixRoom(room_id)