Add initial sync event implementation.
This commit is contained in:
parent
9b25026a3a
commit
2ac8bef499
4 changed files with 282 additions and 244 deletions
|
@ -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
|
|
||||||
|
|
305
matrix/events.py
305
matrix/events.py
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,10 +124,8 @@ 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,
|
",".join([full_name, user.name, user.display_name]))
|
||||||
"highlight_words",
|
|
||||||
",".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_printed': print_date,
|
'date': date,
|
||||||
'tags_array': ','.join(tags),
|
'date_printed': print_date,
|
||||||
'prefix': prefix,
|
'tags_array': ','.join(tags),
|
||||||
'message': message}
|
'prefix': prefix,
|
||||||
|
'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')
|
||||||
|
@ -661,8 +624,8 @@ def matrix_update_buffer_lines(new_lines, own_lines):
|
||||||
|
|
||||||
|
|
||||||
def matrix_handle_message(
|
def matrix_handle_message(
|
||||||
server, # type: MatrixServer
|
server, # type: MatrixServer
|
||||||
message, # type: MatrixMessage
|
message, # type: MatrixMessage
|
||||||
):
|
):
|
||||||
# type: (...) -> None
|
# type: (...) -> None
|
||||||
message_type = message.type
|
message_type = message.type
|
||||||
|
@ -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"), status_code=status_code))
|
||||||
prefix=W.prefix("error"),
|
|
||||||
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
65
matrix/rooms.py
Normal 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)
|
Loading…
Add table
Reference in a new issue