MUC: Save last message time after each message

This commit is contained in:
Philipp Hörist 2017-10-22 00:39:56 +02:00
parent 0aa07522fb
commit 1c7369229e
5 changed files with 14 additions and 45 deletions

View file

@ -665,7 +665,6 @@ class Connection(CommonConnection, ConnectionHandlers):
self.annotations = {} self.annotations = {}
self.last_io = app.idlequeue.current_time() self.last_io = app.idlequeue.current_time()
self.last_sent = [] self.last_sent = []
self.last_history_time = {}
self.password = passwords.get_password(name) self.password = passwords.get_password(name)
self.music_track_info = 0 self.music_track_info = 0
@ -2576,20 +2575,11 @@ class Connection(CommonConnection, ConnectionHandlers):
# Never join a room when invisible # Never join a room when invisible
return return
# last date/time in history to avoid duplicate # Check time first in the FAST table
if room_jid not in self.last_history_time: last_date = app.logger.get_room_last_message_time(
# Not in memory, get it from DB self.name, room_jid)
last_log = 0 if not last_date:
if app.config.should_log(self.name, room_jid): last_date = 0
# Check time first in the FAST table
last_log = app.logger.get_room_last_message_time(
self.name, room_jid)
if not last_log:
last_log = 0
# Create self.last_history_time[room_jid] even if not logging,
# could be used in connection_handlers
self.last_history_time[room_jid] = last_log
p = nbxmpp.Presence(to='%s/%s' % (room_jid, nick), p = nbxmpp.Presence(to='%s/%s' % (room_jid, nick),
show=show, status=self.status) show=show, status=self.status)
@ -2608,7 +2598,6 @@ class Connection(CommonConnection, ConnectionHandlers):
'muc_restore_timeout') 'muc_restore_timeout')
if timeout is None or timeout == -2: if timeout is None or timeout == -2:
timeout = app.config.get('muc_restore_timeout') timeout = app.config.get('muc_restore_timeout')
last_date = self.last_history_time[room_jid]
if last_date == 0 and timeout >= 0: if last_date == 0 and timeout >= 0:
last_date = time.time() - timeout * 60 last_date = time.time() - timeout * 60
elif not rejoin and timeout >= 0: elif not rejoin and timeout >= 0:
@ -2736,16 +2725,6 @@ class Connection(CommonConnection, ConnectionHandlers):
# disconnect from jabber server # disconnect from jabber server
self.connection.send(p) self.connection.send(p)
def gc_got_disconnected(self, room_jid):
"""
A groupchat got disconnected. This can be or purpose or not
Save the time we had last message to avoid duplicate logs AND be faster
than get that date from DB. Save time that we have in mem in a small
table (with fast access)
"""
app.logger.set_room_last_message_time(room_jid, self.last_history_time[room_jid])
def gc_set_role(self, room_jid, nick, role, reason=''): def gc_set_role(self, room_jid, nick, role, reason=''):
""" """
Role is for all the life of the room so it's based on nick Role is for all the life of the room so it's based on nick

View file

@ -1017,9 +1017,8 @@ class ConnectionHandlersBase:
def _nec_gc_message_received(self, obj): def _nec_gc_message_received(self, obj):
if obj.conn.name != self.name: if obj.conn.name != self.name:
return return
if app.config.should_log(obj.conn.name, obj.jid) and not \ if (app.config.should_log(obj.conn.name, obj.jid) and
obj.timestamp < obj.conn.last_history_time[obj.jid] and obj.msgtxt and \ obj.msgtxt and obj.nick):
obj.nick:
# if not obj.nick, it means message comes from room itself # if not obj.nick, it means message comes from room itself
# usually it hold description and can be send at each connection # usually it hold description and can be send at each connection
# so don't store it in logs # so don't store it in logs
@ -1029,10 +1028,7 @@ class ConnectionHandlersBase:
message=obj.msgtxt, message=obj.msgtxt,
contact_name=obj.nick, contact_name=obj.nick,
additional_data=obj.additional_data) additional_data=obj.additional_data)
# store in memory time of last message logged. app.logger.set_room_last_message_time(obj.room_jid, obj.timestamp)
# this will also be saved in rooms_last_message_time table
# when we quit this muc
obj.conn.last_history_time[obj.jid] = obj.timestamp
# process and dispatch an error message # process and dispatch an error message
def dispatch_error_message(self, msg, msgtxt, session, frm, tim): def dispatch_error_message(self, msg, msgtxt, session, frm, tim):

View file

@ -1564,9 +1564,6 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
# Ignore message from room in which we are not # Ignore message from room in which we are not
self.displaymarking = seclabel.getTag('displaymarking') self.displaymarking = seclabel.getTag('displaymarking')
if self.jid not in self.conn.last_history_time:
return
self.captcha_form = None self.captcha_form = None
captcha_tag = self.stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA) captcha_tag = self.stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA)
if captcha_tag: if captcha_tag:

View file

@ -765,13 +765,16 @@ class Logger:
:param jid: The jid :param jid: The jid
:param timestamp: The timestamp in epoch :param timestamp: The timestamp in epoch
""" """
self.insert_jid(jid, type_=JIDConstant.ROOM_TYPE)
jid_id = self.get_jid_id(jid, type_=JIDConstant.ROOM_TYPE)
sql = '''REPLACE INTO rooms_last_message_time sql = '''REPLACE INTO rooms_last_message_time
VALUES ((SELECT jid_id FROM jids WHERE jid = ?), ?)''' VALUES (:jid_id, COALESCE(
(SELECT time FROM rooms_last_message_time
WHERE jid_id = :jid_id AND time >= :time), :time))'''
self.con.execute(sql, (jid, timestamp)) self.con.execute(sql, {"jid_id": jid_id, "time": timestamp})
self._timeout_commit() self._timeout_commit()
def save_transport_type(self, jid, type_): def save_transport_type(self, jid, type_):

View file

@ -1499,8 +1499,6 @@ class GroupchatControl(ChatControlBase):
app.contacts.remove_gc_contact(self.account, gc_contact) app.contacts.remove_gc_contact(self.account, gc_contact)
app.gc_connected[self.account][self.room_jid] = False app.gc_connected[self.account][self.room_jid] = False
ChatControlBase.got_disconnected(self) ChatControlBase.got_disconnected(self)
# Tell connection to note the date we disconnect to avoid duplicate logs
app.connections[self.account].gc_got_disconnected(self.room_jid)
# We don't redraw the whole banner here, because only icon change # We don't redraw the whole banner here, because only icon change
self._update_banner_state_image() self._update_banner_state_image()
if self.parent_win: if self.parent_win:
@ -2141,10 +2139,6 @@ class GroupchatControl(ChatControlBase):
if self.room_jid in app.gc_connected[self.account] and \ if self.room_jid in app.gc_connected[self.account] and \
app.gc_connected[self.account][self.room_jid]: app.gc_connected[self.account][self.room_jid]:
# Tell connection to note the date we disconnect to avoid duplicate
# logs. We do it only when connected because if connection was lost
# there may be new messages since disconnection.
app.connections[self.account].gc_got_disconnected(self.room_jid)
app.connections[self.account].send_gc_status(self.nick, app.connections[self.account].send_gc_status(self.nick,
self.room_jid, show='offline', status=status) self.room_jid, show='offline', status=status)
nick_list = app.contacts.get_nick_list(self.account, self.room_jid) nick_list = app.contacts.get_nick_list(self.account, self.room_jid)