server: Add support for sending out read markers.

This commit is contained in:
Damir Jelić 2018-12-03 22:28:49 +01:00
parent 33a96485ee
commit 9d3b624733
5 changed files with 111 additions and 8 deletions

19
main.py
View file

@ -463,12 +463,16 @@ class WeechatHandler(StreamHandler):
W.prnt(buf, item)
def lazy_fetch_members_signal(_, _signal, buffer_ptr):
""" Fetch room members on a buffer switch signal.
def buffer_switch_cb(_, _signal, buffer_ptr):
"""Do some buffer operations when we switch buffers.
This function is called every time we switch a buffer. The pointer of
the new buffer is given to us by weechat. If it is one of our room buffers
we check if the members for the room aren't fetched and fetch them now if
they aren't.
the new buffer is given to us by weechat.
If it is one of our room buffers we check if the members for the room
aren't fetched and fetch them now if they aren't.
Read receipts are send out from here as well.
"""
for server in SERVERS.values():
if buffer_ptr == server.server_buffer:
@ -481,6 +485,9 @@ def lazy_fetch_members_signal(_, _signal, buffer_ptr):
if not room_buffer:
continue
if room_buffer.should_send_read_marker:
server.room_send_read_marker(room_buffer)
if room_buffer.members_fetched:
return W.WEECHAT_RC_OK
@ -533,7 +540,7 @@ if __name__ == "__main__":
init_bar_items()
init_completion()
W.hook_signal("buffer_switch", "lazy_fetch_members_signal", "")
W.hook_signal("buffer_switch", "buffer_switch_cb", "")
W.hook_signal("input_text_changed", "typing_notification_cb", "")
if not SERVERS:

View file

@ -829,6 +829,9 @@ class RoomBuffer(object):
self._typing = False
self.typing_enabled = True
self.last_read_event = None
self._read_markers_enabled = True
buffer_name = "{}.{}".format(server_name, room.room_id)
# This dict remembers the connection from a user_id to the name we
@ -899,6 +902,48 @@ class RoomBuffer(object):
return True
return False
@property
def should_send_read_marker(self):
# type () -> bool
"""Check if we need to send out a read receipt."""
if not self.read_markers_enabled:
return False
if not self.last_read_event:
return True
if self.last_read_event == self.last_event_id:
return False
return True
@property
def last_event_id(self):
# type () -> str
"""Get the event id of the last shown matrix event."""
for line in self.weechat_buffer.lines:
for tag in line.tags:
if tag.startswith("matrix_id"):
event_id = tag[10:]
return event_id
return ""
@property
def read_markers_enabled(self):
# type: () -> bool
"""Check if read receipts are enabled for this room."""
return bool(int(W.string_eval_expression(
G.CONFIG.network.read_markers_conditions,
{},
{"markers_enabled": str(int(self._read_markers_enabled))},
{"type": "condition"}
)))
@read_markers_enabled.setter
def read_markers_enabled(self, value):
self._read_markers_enabled = value
def find_nick(self, user_id):
# type: (str) -> str
"""Find a suitable nick from a user_id."""

View file

@ -151,6 +151,12 @@ class WeechatCommandParser(object):
choices=["enable", "disable", "toggle"]
)
read_markers = subparsers.add_parser("read-markers")
read_markers.add_argument(
"state",
choices=["enable", "disable", "toggle"]
)
return WeechatCommandParser._run_parser(parser, args)
@ -376,12 +382,15 @@ def hook_commands():
"room",
"change room state",
# Synopsis
("typing-notifications <state>"
("typing-notifications <state>||"
"read-markers <state>"
),
# Description
("state: one of enable, disable or toggle\n"),
# Completions
("typing-notifications enable|disable|toggle"),
("typing-notifications enable|disable|toggle||"
"read-markers enable|disable|toggle"
),
# Callback
"matrix_room_command_cb",
"",
@ -915,6 +924,15 @@ def matrix_room_command_cb(data, buffer, args):
room.typing_enabled = not room.typing_enabled
break
elif parsed_args.subcommand == "read-markers":
if parsed_args.state == "enable":
room.read_markers_enabled = True
elif parsed_args.state == "disable":
room.read_markers_enabled = False
elif parsed_args.state == "toggle":
room.read_markers_enabled = not room.read_markers_enabled
break
return W.WEECHAT_RC_OK

View file

@ -625,6 +625,19 @@ class MatrixConfig(WeechatConfig):
"the typing_enabled variable can be manipulated with the "
"/room command, see /help room"),
),
Option(
"read_markers_conditions",
"string",
"",
0,
0,
"${markers_enabled}",
("conditions to send read markers (note: content is "
"evaluated, see /help eval); besides the buffer and window "
"variables the markers_enabled variable is also expanded; "
"the markers_enabled variable can be manipulated with the "
"/room command, see /help room"),
),
]
color_options = [

View file

@ -673,6 +673,26 @@ class MatrixServer(object):
self.backlog_queue[uuid] = room_id
self.send_or_queue(request)
def room_send_read_marker(self, room_buffer):
"""Send read markers for the provided room.
Args:
room_buffer(RoomBuffer): the room for which the read markers should
be sent.
"""
if not self.connected:
return
event_id = room_buffer.last_event_id
_, request = self.client.room_read_markers(
room_buffer.room.room_id,
fully_read_event=event_id,
read_event=event_id)
self.send(request)
room_buffer.last_read_event = event_id
def room_send_typing_notice(self, room_buffer):
"""Send a typing notice for the provided room.