Philipp Hörist pushed to branch correction at gajim / gajim
Commits:
-
dccc7f6a
by lovetox at 2022-09-03T09:31:05+02:00
5 changed files:
- gajim/common/const.py
- gajim/common/modules/mam.py
- gajim/common/modules/message.py
- gajim/common/modules/util.py
- gajim/common/storage/archive.py
Changes:
| ... | ... | @@ -36,6 +36,8 @@ |
| 36 | 36 | STOP_EVENT = True
|
| 37 | 37 | PROPAGATE_EVENT = False
|
| 38 | 38 | |
| 39 | +MAX_MESSAGE_CORRECTION_DELAY = 300
|
|
| 40 | + |
|
| 39 | 41 | |
| 40 | 42 | class EncryptionData(NamedTuple):
|
| 41 | 43 | additional_data: Any = None
|
| ... | ... | @@ -43,7 +43,6 @@ |
| 43 | 43 | from gajim.common.events import ArchivingIntervalFinished
|
| 44 | 44 | from gajim.common.events import FeatureDiscovered
|
| 45 | 45 | from gajim.common.events import MamMessageReceived
|
| 46 | -from gajim.common.events import MessageUpdated
|
|
| 47 | 46 | from gajim.common.events import RawMamMessageReceived
|
| 48 | 47 | from gajim.common.const import ArchiveState, ClientState
|
| 49 | 48 | from gajim.common.const import KindConstant
|
| ... | ... | @@ -51,7 +50,7 @@ |
| 51 | 50 | from gajim.common.helpers import AdditionalDataDict
|
| 52 | 51 | from gajim.common.helpers import get_retraction_text
|
| 53 | 52 | from gajim.common.modules.misc import parse_oob
|
| 54 | -from gajim.common.modules.misc import parse_correction
|
|
| 53 | +from gajim.common.modules.util import check_if_message_correction
|
|
| 55 | 54 | from gajim.common.modules.util import get_eme_message
|
| 56 | 55 | from gajim.common.modules.util import as_task
|
| 57 | 56 | from gajim.common.modules.base import BaseModule
|
| ... | ... | @@ -311,21 +310,12 @@ def _mam_message_received(self, |
| 311 | 310 | 'kind': kind,
|
| 312 | 311 | }
|
| 313 | 312 | |
| 314 | - correct_id = parse_correction(properties)
|
|
| 315 | - if correct_id is not None:
|
|
| 316 | - nickname = properties.muc_nickname or properties.nickname
|
|
| 317 | - app.ged.raise_event(MessageUpdated(account=self._account,
|
|
| 318 | - jid=jid,
|
|
| 319 | - msgtxt=properties.body,
|
|
| 320 | - nickname=nickname,
|
|
| 321 | - properties=properties,
|
|
| 322 | - correct_id=correct_id))
|
|
| 323 | - app.storage.archive.store_message_correction(
|
|
| 324 | - self._account,
|
|
| 325 | - jid,
|
|
| 326 | - correct_id,
|
|
| 327 | - properties.body,
|
|
| 328 | - properties.type.is_groupchat)
|
|
| 313 | + if check_if_message_correction(properties,
|
|
| 314 | + self._account,
|
|
| 315 | + properties.jid,
|
|
| 316 | + properties.body,
|
|
| 317 | + kind,
|
|
| 318 | + self._log):
|
|
| 329 | 319 | return
|
| 330 | 320 | |
| 331 | 321 | app.storage.archive.insert_into_logs(
|
| ... | ... | @@ -32,13 +32,12 @@ |
| 32 | 32 | from gajim.common.events import GcMessageReceived
|
| 33 | 33 | from gajim.common.events import MessageError
|
| 34 | 34 | from gajim.common.events import MessageReceived
|
| 35 | -from gajim.common.events import MessageUpdated
|
|
| 36 | 35 | from gajim.common.events import RawMessageReceived
|
| 37 | 36 | from gajim.common.helpers import AdditionalDataDict
|
| 38 | 37 | from gajim.common.const import KindConstant
|
| 39 | 38 | from gajim.common.modules.base import BaseModule
|
| 39 | +from gajim.common.modules.util import check_if_message_correction
|
|
| 40 | 40 | from gajim.common.modules.util import get_eme_message
|
| 41 | -from gajim.common.modules.misc import parse_correction
|
|
| 42 | 41 | from gajim.common.modules.misc import parse_oob
|
| 43 | 42 | from gajim.common.modules.misc import parse_xhtml
|
| 44 | 43 | from gajim.common.structs import OutgoingMessage
|
| ... | ... | @@ -190,23 +189,19 @@ def _message_received(self, |
| 190 | 189 | 'properties': properties,
|
| 191 | 190 | }
|
| 192 | 191 | |
| 193 | - correct_id = parse_correction(properties)
|
|
| 194 | - if correct_id is not None:
|
|
| 195 | - nickname = properties.muc_nickname or properties.nickname
|
|
| 196 | - event = MessageUpdated(account=self._account,
|
|
| 197 | - jid=event_attr['jid'],
|
|
| 198 | - msgtxt=msgtxt,
|
|
| 199 | - nickname=nickname,
|
|
| 200 | - properties=properties,
|
|
| 201 | - correct_id=correct_id)
|
|
| 202 | - |
|
| 203 | - app.storage.archive.store_message_correction(
|
|
| 204 | - self._account,
|
|
| 205 | - jid,
|
|
| 206 | - correct_id,
|
|
| 207 | - msgtxt,
|
|
| 208 | - properties.type.is_groupchat)
|
|
| 209 | - app.ged.raise_event(event)
|
|
| 192 | + if type_.is_groupchat:
|
|
| 193 | + kind = KindConstant.GC_MSG
|
|
| 194 | + elif properties.is_sent_carbon:
|
|
| 195 | + kind = KindConstant.CHAT_MSG_SENT
|
|
| 196 | + else:
|
|
| 197 | + kind = KindConstant.CHAT_MSG_RECV
|
|
| 198 | + |
|
| 199 | + if check_if_message_correction(properties,
|
|
| 200 | + self._account,
|
|
| 201 | + from_,
|
|
| 202 | + msgtxt,
|
|
| 203 | + kind,
|
|
| 204 | + self._log):
|
|
| 210 | 205 | return
|
| 211 | 206 | |
| 212 | 207 | if type_.is_groupchat:
|
| ... | ... | @@ -224,10 +219,6 @@ def _message_received(self, |
| 224 | 219 | |
| 225 | 220 | app.ged.raise_event(MessageReceived(**event_attr))
|
| 226 | 221 | |
| 227 | - log_type = KindConstant.CHAT_MSG_RECV
|
|
| 228 | - if properties.is_sent_carbon:
|
|
| 229 | - log_type = KindConstant.CHAT_MSG_SENT
|
|
| 230 | - |
|
| 231 | 222 | if not msgtxt:
|
| 232 | 223 | return
|
| 233 | 224 | |
| ... | ... | @@ -235,7 +226,7 @@ def _message_received(self, |
| 235 | 226 | self._account,
|
| 236 | 227 | fjid if properties.is_muc_pm else jid,
|
| 237 | 228 | properties.timestamp,
|
| 238 | - log_type,
|
|
| 229 | + kind,
|
|
| 239 | 230 | message=msgtxt,
|
| 240 | 231 | subject=properties.subject,
|
| 241 | 232 | additional_data=additional_data,
|
| ... | ... | @@ -399,12 +390,13 @@ def log_message(self, message: OutgoingMessage) -> None: |
| 399 | 390 | return
|
| 400 | 391 | |
| 401 | 392 | if message.correct_id is not None:
|
| 402 | - app.storage.archive.store_message_correction(
|
|
| 393 | + app.storage.archive.try_message_correction(
|
|
| 403 | 394 | self._account,
|
| 404 | 395 | message.jid,
|
| 405 | - message.correct_id,
|
|
| 396 | + None,
|
|
| 406 | 397 | message.message,
|
| 407 | - message.is_groupchat)
|
|
| 398 | + message.correct_id,
|
|
| 399 | + KindConstant.CHAT_MSG_SENT)
|
|
| 408 | 400 | return
|
| 409 | 401 | |
| 410 | 402 | app.storage.archive.insert_into_logs(
|
| ... | ... | @@ -19,19 +19,25 @@ |
| 19 | 19 | from typing import Any
|
| 20 | 20 | from typing import Union
|
| 21 | 21 | |
| 22 | +import logging
|
|
| 22 | 23 | from logging import LoggerAdapter
|
| 23 | 24 | from functools import wraps
|
| 24 | 25 | from functools import partial
|
| 25 | 26 | |
| 26 | 27 | import nbxmpp
|
| 28 | +from nbxmpp.protocol import JID
|
|
| 27 | 29 | from nbxmpp.protocol import Message
|
| 28 | 30 | from nbxmpp.structs import EMEData
|
| 29 | 31 | from nbxmpp.structs import MessageProperties
|
| 32 | +from nbxmpp.const import MessageType
|
|
| 30 | 33 | from nbxmpp.task import Task
|
| 31 | 34 | |
| 32 | 35 | from gajim.common import app
|
| 33 | 36 | from gajim.common import types
|
| 34 | 37 | from gajim.common.const import EME_MESSAGES
|
| 38 | +from gajim.common.const import KindConstant
|
|
| 39 | +from gajim.common.events import MessageUpdated
|
|
| 40 | +from gajim.common.modules.misc import parse_correction
|
|
| 35 | 41 | |
| 36 | 42 | |
| 37 | 43 | def from_xs_boolean(value: Union[str, bool]) -> bool:
|
| ... | ... | @@ -115,3 +121,57 @@ def func_wrapper(self, *args, callback=None, user_data=None, **kwargs): |
| 115 | 121 | task_.start()
|
| 116 | 122 | return task_
|
| 117 | 123 | return func_wrapper
|
| 124 | + |
|
| 125 | + |
|
| 126 | +def check_if_message_correction(properties: MessageProperties,
|
|
| 127 | + account: str,
|
|
| 128 | + jid: JID,
|
|
| 129 | + msgtxt: str,
|
|
| 130 | + kind: KindConstant,
|
|
| 131 | + logger: LoggerAdapter[logging.Logger]) -> bool:
|
|
| 132 | + |
|
| 133 | + correct_id = parse_correction(properties)
|
|
| 134 | + if correct_id is None:
|
|
| 135 | + return False
|
|
| 136 | + |
|
| 137 | + if properties.type not in (MessageType.GROUPCHAT, MessageType.CHAT):
|
|
| 138 | + logger.warning('Ignore correction with message type: %s',
|
|
| 139 | + properties.type)
|
|
| 140 | + return False
|
|
| 141 | + |
|
| 142 | + nickname = None
|
|
| 143 | + if properties.type.is_groupchat:
|
|
| 144 | + if jid.is_bare:
|
|
| 145 | + logger.warning(
|
|
| 146 | + 'Ignore correction from bare groupchat jid: %s', jid)
|
|
| 147 | + return False
|
|
| 148 | + |
|
| 149 | + nickname = jid.resource
|
|
| 150 | + jid = jid.new_as_bare()
|
|
| 151 | + |
|
| 152 | + elif not properties.is_muc_pm:
|
|
| 153 | + jid = jid.new_as_bare()
|
|
| 154 | + |
|
| 155 | + successful = app.storage.archive.try_message_correction(
|
|
| 156 | + account,
|
|
| 157 | + jid,
|
|
| 158 | + nickname,
|
|
| 159 | + msgtxt,
|
|
| 160 | + correct_id,
|
|
| 161 | + kind)
|
|
| 162 | + |
|
| 163 | + if not successful:
|
|
| 164 | + logger.info('Message correction not successful')
|
|
| 165 | + return False
|
|
| 166 | + |
|
| 167 | + nickname = properties.muc_nickname or properties.nickname
|
|
| 168 | + |
|
| 169 | + event = MessageUpdated(account=account,
|
|
| 170 | + jid=jid,
|
|
| 171 | + msgtxt=msgtxt,
|
|
| 172 | + nickname=nickname,
|
|
| 173 | + properties=properties,
|
|
| 174 | + correct_id=correct_id)
|
|
| 175 | + |
|
| 176 | + app.ged.raise_event(event)
|
|
| 177 | + return True |
| ... | ... | @@ -42,6 +42,7 @@ |
| 42 | 42 | from gajim.common import app
|
| 43 | 43 | from gajim.common import configpaths
|
| 44 | 44 | from gajim.common.helpers import AdditionalDataDict
|
| 45 | +from gajim.common.const import MAX_MESSAGE_CORRECTION_DELAY
|
|
| 45 | 46 | from gajim.common.const import ShowConstant
|
| 46 | 47 | from gajim.common.const import KindConstant
|
| 47 | 48 | from gajim.common.const import JIDConstant
|
| ... | ... | @@ -991,7 +992,7 @@ def get_last_correctable_message(self, |
| 991 | 992 | '''
|
| 992 | 993 | jids = [jid]
|
| 993 | 994 | account_id = self.get_account_id(account)
|
| 994 | - min_time = time.time() - 5 * 60
|
|
| 995 | + min_time = time.time() - MAX_MESSAGE_CORRECTION_DELAY
|
|
| 995 | 996 | |
| 996 | 997 | sql = '''
|
| 997 | 998 | SELECT contact_name, time, kind, message, stanza_id, message_id,
|
| ... | ... | @@ -1008,29 +1009,57 @@ def get_last_correctable_message(self, |
| 1008 | 1009 | tuple(jids) + (message_id, min_time)).fetchone()
|
| 1009 | 1010 | |
| 1010 | 1011 | @timeit
|
| 1011 | - def store_message_correction(self,
|
|
| 1012 | - account: str,
|
|
| 1013 | - jid: JID,
|
|
| 1014 | - correct_id: str,
|
|
| 1015 | - corrected_text: str,
|
|
| 1016 | - is_groupchat: bool) -> None:
|
|
| 1017 | - type_ = JIDConstant.NORMAL_TYPE
|
|
| 1018 | - if is_groupchat:
|
|
| 1019 | - type_ = JIDConstant.ROOM_TYPE
|
|
| 1012 | + def try_message_correction(self,
|
|
| 1013 | + account: str,
|
|
| 1014 | + jid: JID,
|
|
| 1015 | + nickname: Optional[str],
|
|
| 1016 | + corrected_text: str,
|
|
| 1017 | + correct_id: str,
|
|
| 1018 | + kind: KindConstant) -> bool:
|
|
| 1019 | + |
|
| 1020 | + '''Try to correct a message
|
|
| 1021 | + |
|
| 1022 | + :param jid: This can be a full jid or bare jid. A full jid only if the
|
|
| 1023 | + message is a MUC PM, otherwise a bare jid needs to be
|
|
| 1024 | + passed. `nickname` should only be passed if the message
|
|
| 1025 | + is a group chat message.
|
|
| 1026 | + '''
|
|
| 1020 | 1027 | |
| 1021 | - jid_id = self.get_jid_id(str(jid), type_=type_)
|
|
| 1022 | 1028 | account_id = self.get_account_id(account)
|
| 1023 | - sql = '''
|
|
| 1024 | - SELECT log_line_id, message, additional_data
|
|
| 1025 | - FROM logs
|
|
| 1026 | - WHERE +jid_id = ?
|
|
| 1027 | - AND account_id = ?
|
|
| 1028 | - AND message_id = ?
|
|
| 1029 | - '''
|
|
| 1030 | - row = self._con.execute(
|
|
| 1031 | - sql, (jid_id, account_id, correct_id)).fetchone()
|
|
| 1032 | - if row is None:
|
|
| 1033 | - return
|
|
| 1029 | + max_timestamp = time.time() - MAX_MESSAGE_CORRECTION_DELAY
|
|
| 1030 | + |
|
| 1031 | + self._log.debug(
|
|
| 1032 | + 'Check if message is correctable, parameters: %s %s %s %s %s',
|
|
| 1033 | + jid, account_id, nickname, correct_id, max_timestamp)
|
|
| 1034 | + |
|
| 1035 | + sql = '''SELECT log_line_id, message, additional_data
|
|
| 1036 | + FROM logs
|
|
| 1037 | + NATURAL JOIN jids jid_id
|
|
| 1038 | + WHERE +jid = ?
|
|
| 1039 | + AND account_id = ?
|
|
| 1040 | + AND contact_name IS ?
|
|
| 1041 | + AND message_id = ?
|
|
| 1042 | + AND kind = ?
|
|
| 1043 | + AND time > ?
|
|
| 1044 | + '''
|
|
| 1045 | + |
|
| 1046 | + rows = self._con.execute(sql, (jid,
|
|
| 1047 | + account_id,
|
|
| 1048 | + nickname,
|
|
| 1049 | + correct_id,
|
|
| 1050 | + kind,
|
|
| 1051 | + max_timestamp
|
|
| 1052 | + )).fetchall()
|
|
| 1053 | + |
|
| 1054 | + if not rows:
|
|
| 1055 | + self._log.debug('No correctable messages found')
|
|
| 1056 | + return False
|
|
| 1057 | + |
|
| 1058 | + if len(rows) != 1:
|
|
| 1059 | + self._log.warning('More than one correctable message found')
|
|
| 1060 | + return False
|
|
| 1061 | + |
|
| 1062 | + row = rows[0]
|
|
| 1034 | 1063 | |
| 1035 | 1064 | if row.additional_data is None:
|
| 1036 | 1065 | additional_data = AdditionalDataDict()
|
| ... | ... | @@ -1052,6 +1081,8 @@ def store_message_correction(self, |
| 1052 | 1081 | self._con.execute(
|
| 1053 | 1082 | sql, (corrected_text, serialized_dict, row.log_line_id))
|
| 1054 | 1083 | |
| 1084 | + return True
|
|
| 1085 | + |
|
| 1055 | 1086 | @timeit
|
| 1056 | 1087 | def update_additional_data(self,
|
| 1057 | 1088 | account: str,
|