Mercurial > libervia-pubsub
annotate sat_pubsub/mam.py @ 367:a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
/!\ this patch updates pgqsl schema /!\
Had to set 2 features in the same patch, to avoid updating 2 times the schema.
1) creation/last modification date:
column keeping the date of creation of items is renamed from "date" to "created"
the date of last modification of items is saved in the new "updated" column
2) serial ids:
this experimental feature allows to have ids in series (i.e. 1, 2, 3, etc.) instead of UUID.
This is a convenience feature and there are some drawbacks:
- PostgreSQL sequences are used, so gaps can happen (see PostgreSQL documentation for more details)
- if somebody create an item with a future id in the series, the series will adapt, which can have undesired effect, and may lead to item fail if several items are created at the same time. For instance if next id in series is "8", and somebody hads already created item "8" and "256", the item will be created with biggest value in items +1 (i.e. 257). if 2 people want to create item in this situation, the second will fail with a conflict error.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 04 Nov 2017 21:31:32 +0100 |
parents | 5580f08c7b91 |
children |
rev | line source |
---|---|
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
1 #!/usr/bin/python |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
2 #-*- coding: utf-8 -*- |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
3 |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
4 # Copyright (c) 2016 Jérôme Poisson |
311 | 5 # Copyright (c) 2015-2016 Adrien Cossa |
6 # | |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 # | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 # | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
20 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
21 XMPP Message Archive Management protocol. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
22 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
23 This protocol is specified in |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
24 U{XEP-0313<http://xmpp.org/extensions/xep-0313.html>}. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
25 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
26 |
311 | 27 |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
28 from zope.interface import implements |
281
30895c49ebd2
fixes the imports from sat.tmp
souliane <souliane@mailoo.org>
parents:
280
diff
changeset
|
29 |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
30 from twisted.words.xish import domish |
322 | 31 from twisted.python import log |
32 from twisted.words.protocols.jabber import error | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
33 |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
34 from sat_pubsub import const |
322 | 35 from sat_pubsub import backend |
36 from wokkel import pubsub | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
37 |
322 | 38 from wokkel import rsm |
39 from wokkel import mam | |
40 from wokkel import delay | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
41 |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
42 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
43 class MAMResource(object): |
322 | 44 implements(mam.IMAMResource) |
45 _errorMap = backend.PubSubResourceFromBackend._errorMap | |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
46 |
322 | 47 def __init__(self, backend_): |
48 self.backend = backend_ | |
49 | |
50 def _mapErrors(self, failure): | |
51 # XXX: come from backend.PubsubResourceFromBackend | |
52 e = failure.trap(*self._errorMap.keys()) | |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
53 |
322 | 54 condition, pubsubCondition, feature = self._errorMap[e] |
55 msg = failure.value.msg | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
56 |
322 | 57 if pubsubCondition: |
58 exc = pubsub.PubSubError(condition, pubsubCondition, feature, msg) | |
59 else: | |
60 exc = error.StanzaError(condition, text=msg) | |
61 | |
62 raise exc | |
63 | |
325
8d939378f023
mam: removed requestor in favor of mam_request.sender and recipient + fixed bad use of requestor instead of recipient in getItemsData
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
64 def onArchiveRequest(self, mam_request): |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
65 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
66 |
322 | 67 @param mam_request: The MAM archive request. |
68 @type mam_request: L{MAMQueryReques<wokkel.mam.MAMRequest>} | |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
69 |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
70 @return: A tuple with list of message data (id, element, data) and RSM element |
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
71 @rtype: C{tuple} |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
72 """ |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
73 # FIXME: bad result ordering |
322 | 74 try: |
75 pep = mam_request.delegated | |
76 except AttributeError: | |
77 pep = False | |
78 ext_data = {'pep': pep} | |
79 if mam_request.form: | |
80 ext_data['filters'] = mam_request.form.fields.values() | |
81 if mam_request.rsm is None: | |
82 if const.VAL_RSM_MAX_DEFAULT != None: | |
83 log.msg("MAM request without RSM limited to {}".format(const.VAL_RSM_MAX_DEFAULT)) | |
84 ext_data['rsm'] = rsm.RSMRequest(const.VAL_RSM_MAX_DEFAULT) | |
85 else: | |
86 ext_data['rsm'] = mam_request.rsm | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
87 |
335
5580f08c7b91
mam: fixed call to getItemsData where requestor was missing
Goffi <goffi@goffi.org>
parents:
325
diff
changeset
|
88 d = self.backend.getItemsData(mam_request.node, mam_request.sender, mam_request.recipient, None, None, ext_data) |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
89 |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
90 def make_message(elt): |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
91 # XXX: http://xmpp.org/extensions/xep-0297.html#sect-idp629952 (rule 3) |
322 | 92 message = domish.Element((const.NS_CLIENT, "message")) |
93 event = message.addElement((pubsub.NS_PUBSUB_EVENT, "event")) | |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
94 items = event.addElement('items') |
322 | 95 items["node"] = mam_request.node |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
96 items.addChild(elt) |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
97 return message |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
98 |
322 | 99 def cb(items_data): |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
100 msg_data = [] |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
101 rsm_elt = None |
322 | 102 for item_data in items_data: |
103 if item_data.item.name == 'set' and item_data.item.uri == rsm.NS_RSM: | |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
104 assert rsm_elt is None |
322 | 105 rsm_elt = item_data.item |
106 elif item_data.item.name == 'item': | |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
335
diff
changeset
|
107 msg_data.append([item_data.item['id'], make_message(item_data.item), item_data.created]) |
322 | 108 else: |
109 log.msg("WARNING: unknown element: {}".format(item_data.item.name)) | |
110 if pep: | |
111 # we need to send privileged message | |
112 # so me manage the sending ourself, and return | |
113 # an empty msg_data list to avoid double sending | |
114 for data in msg_data: | |
325
8d939378f023
mam: removed requestor in favor of mam_request.sender and recipient + fixed bad use of requestor instead of recipient in getItemsData
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
115 self.forwardPEPMessage(mam_request, *data) |
322 | 116 msg_data = [] |
282
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
117 return (msg_data, rsm_elt) |
7d54ff2eeaf2
actually retrieve the MAM messages
souliane <souliane@mailoo.org>
parents:
281
diff
changeset
|
118 |
322 | 119 d.addErrback(self._mapErrors) |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
120 d.addCallback(cb) |
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
121 return d |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
122 |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
335
diff
changeset
|
123 def forwardPEPMessage(self, mam_request, id_, elt, created): |
322 | 124 msg = domish.Element((None, 'message')) |
125 msg['from'] = self.backend.privilege.server_jid.full() | |
325
8d939378f023
mam: removed requestor in favor of mam_request.sender and recipient + fixed bad use of requestor instead of recipient in getItemsData
Goffi <goffi@goffi.org>
parents:
322
diff
changeset
|
126 msg['to'] = mam_request.sender.full() |
322 | 127 result = msg.addElement((mam.NS_MAM, 'result')) |
128 if mam_request.query_id is not None: | |
129 result['queryid'] = mam_request.query_id | |
130 result['id'] = id_ | |
131 forward = result.addElement((const.NS_FORWARD, 'forwarded')) | |
367
a772f7dac930
backend, storage(pgsql): creation/update date + serial ids:
Goffi <goffi@goffi.org>
parents:
335
diff
changeset
|
132 forward.addChild(delay.Delay(created).toElement()) |
322 | 133 forward.addChild(elt) |
134 self.backend.privilege.sendMessage(msg) | |
135 | |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
136 def onPrefsGetRequest(self, requestor): |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
137 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
138 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
139 @param requestor: JID of the requestor. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
140 @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>} |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
141 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
142 @return: The current settings. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
143 @rtype: L{wokkel.mam.MAMPrefs} |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
144 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
145 # TODO: return the actual current settings |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
146 return mam.MAMPrefs() |
280
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
147 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
148 def onPrefsSetRequest(self, prefs, requestor): |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
149 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
150 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
151 @param prefs: The new settings to set. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
152 @type prefs: L{wokkel.mam.MAMPrefs} |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
153 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
154 @param requestor: JID of the requestor. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
155 @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>} |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
156 |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
157 @return: The settings that have actually been set. |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
158 @rtype: L{wokkel.mam.MAMPrefs} |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
159 """ |
798cb8962c0b
MAM (XEP-0313) support: first draft
souliane <souliane@mailoo.org>
parents:
diff
changeset
|
160 # TODO: set the new settings and return them |
316
cca47e9977a5
mam: minor improvments (module import and some checks)
Goffi <goffi@goffi.org>
parents:
311
diff
changeset
|
161 return mam.MAMPrefs() |