annotate sat/plugins/plugin_xep_0359.py @ 2716:06160b529da6

core (memory/sqlite): changed history constraint /!\ Database schema change /!\ History was using a unique constraint on `profile_id, timestamp, source, dest, source_res, dest_res`, which can cause trouble because several messages send quickly by the same person can have a common timestamp (specially with delayed messages where precision is second), resulting in message loss. The new constraint use `profile_id, stanza_id, source, dest` where `stanza_id` is XEP-0359 stanza_id, so it's unique by definition, and no message should be lost anymore. Because sqlite doesn't support altering table with a constraint change, we have to create new tables and copy old data to new one, which can be pretty long. Sqlite update mechanism with "specifics" has been fixed when several updates are applied (e.g. moving from v5 to v7) and a specific is in the workflow.
author Goffi <goffi@goffi.org>
date Sun, 09 Dec 2018 14:07:26 +0100
parents 5849dcaab99d
children 003b8b4b56a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2696
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
3
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SAT plugin for Message Archive Management (XEP-0359)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # Copyright (C) 2013-2016 Adrien Cossa (souliane@mailoo.org)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
7
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # This program is free software: you can redistribute it and/or modify
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # it under the terms of the GNU Affero General Public License as published by
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # the Free Software Foundation, either version 3 of the License, or
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # (at your option) any later version.
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
12
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # This program is distributed in the hope that it will be useful,
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # GNU Affero General Public License for more details.
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
17
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # You should have received a copy of the GNU Affero General Public License
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
20
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.constants import Const as C
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core import exceptions
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core.i18n import _
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core.log import getLogger
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import xmlstream
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from zope.interface import implements
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from wokkel import disco
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
28
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
29 log = getLogger(__name__)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
30
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
31
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
32 PLUGIN_INFO = {
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
33 C.PI_NAME: u"Unique and Stable Stanza IDs",
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
34 C.PI_IMPORT_NAME: u"XEP-0359",
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
35 C.PI_TYPE: u"XEP",
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
36 C.PI_PROTOCOLS: [u"XEP-0359"],
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
37 C.PI_MAIN: u"XEP_0359",
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
38 C.PI_HANDLER: u"yes",
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
39 C.PI_DESCRIPTION: _(u"""Implementation of Unique and Stable Stanza IDs"""),
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
40 }
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
41
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
42 NS_SID = u"urn:xmpp:sid:0"
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
43
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
44
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
45 class XEP_0359(object):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
46
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
47 def __init__(self, host):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
48 log.info(_(u"Unique and Stable Stanza IDs plugin initialization"))
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
49 self.host = host
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
50 host.registerNamespace(u"stanza_id", NS_SID)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
51 host.trigger.add(u"message_parse", self._message_parseTrigger)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
52
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
53 def _message_parseTrigger(self, client, message_elt, mess_data):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
54 """Check if message has a stanza-id"""
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
55 stanza_id = self.getStanzaId(message_elt, client.jid.userhostJID())
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
56 if stanza_id is not None:
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
57 mess_data[u'extra'][u'stanza_id'] = stanza_id
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
58 return True
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
59
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
60 def getStanzaId(self, element, by):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
61 """Return stanza-id if found in element
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
62
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
63 @param element(domish.Element): element to parse
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
64 @param by(jid.JID): entity which should have set a stanza-id
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
65 @return (unicode, None): stanza-id if found
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
66 """
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
67 stanza_id = None
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
68 for stanza_elt in element.elements(NS_SID, u"stanza-id"):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
69 if stanza_elt.getAttribute(u"by") == by.full():
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
70 if stanza_id is not None:
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
71 # we must not have more than one element (§3 #4)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
72 raise exceptions.DataError(
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
73 u"More than one corresponding stanza-id found!")
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
74 stanza_id = stanza_elt.getAttribute(u"id")
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
75 # we don't break to be sure that there is no more than one element
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
76 # with this "by" attribute
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
77
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
78 return stanza_id
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
79
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
80 def addStanzaId(self, client, element, stanza_id, by=None):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
81 """Add a <stanza-id/> to a stanza
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
82
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
83 @param element(domish.Element): stanza where the <stanza-id/> must be added
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
84 @param stanza_id(unicode): id to use
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
85 @param by(jid.JID, None): jid to use or None to use client.jid
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
86 """
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
87 sid_elt = element.addElement((NS_SID, u"stanza-id"))
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
88 sid_elt[u"by"] = client.jid.userhost() if by is None else by.userhost()
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
89 sid_elt[u"id"] = stanza_id
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
90
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
91 def getHandler(self, client):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
92 return XEP_0359_handler()
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
93
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
94
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
95 class XEP_0359_handler(xmlstream.XMPPHandler):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
96 implements(disco.IDisco)
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
97
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
98 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
99 return [disco.DiscoFeature(NS_SID)]
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
100
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
101 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
5849dcaab99d plugin XEP-0359: Unique and Stable Stanza IDs implementation, first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
102 return []