Mercurial > libervia-pubsub
annotate src/schema.py @ 403:1dc606612405
implemented experimental "consistent_publisher" option:
/!\ pgsql schema needs to be updated /!\
New "consistent_publisher" option has been implemented to allow node owners + admins to
modify an item while preserving the original publisher. This way, original publisher can
still edit the item.
In addition to `consistent_publisher`, `max_items` has been added to PGQSL schema to
prepare for future implementation.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 12 Jun 2019 21:51:50 +0200 |
parents | dabee42494ac |
children |
rev | line source |
---|---|
352 | 1 #!/usr/bin/python |
2 #-*- coding: utf-8 -*- | |
3 # | |
4 # Copyright (c) 2015 Jérôme Poisson | |
5 | |
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 | |
20 # --- | |
21 | |
22 # This module implements node schema | |
23 | |
24 from twisted.words.protocols.jabber import jid | |
25 from twisted.words.xish import domish | |
26 from wokkel import disco, iwokkel | |
27 from wokkel.iwokkel import IPubSubService | |
28 from wokkel.subprotocols import XMPPHandler, IQHandlerMixin | |
29 from wokkel import data_form, pubsub | |
30 from zope.interface import implements | |
31 from sat_pubsub import const | |
32 | |
33 QUERY_SCHEMA = "/pubsub[@xmlns='" + const.NS_SCHEMA + "']" | |
34 | |
35 | |
36 class SchemaHandler(XMPPHandler, IQHandlerMixin): | |
37 implements(iwokkel.IDisco) | |
38 iqHandlers = {"/iq[@type='get']" + QUERY_SCHEMA: 'onSchemaGet', | |
39 "/iq[@type='set']" + QUERY_SCHEMA: 'onSchemaSet'} | |
40 | |
41 def __init__(self): | |
42 super(SchemaHandler, self).__init__() | |
43 self.pubsub_service = None | |
44 | |
45 def connectionInitialized(self): | |
46 for handler in self.parent.handlers: | |
47 if IPubSubService.providedBy(handler): | |
48 self.pubsub_service = handler | |
49 break | |
50 self.backend = self.parent.parent.getServiceNamed('backend') | |
51 self.xmlstream.addObserver("/iq[@type='get' or @type='set']" + QUERY_SCHEMA, self.handleRequest) | |
52 | |
53 def _getNodeSchemaCb(self, x_elt, nodeIdentifier): | |
54 schema_elt = domish.Element((const.NS_SCHEMA, 'schema')) | |
55 schema_elt['node'] = nodeIdentifier | |
56 if x_elt is not None: | |
57 assert x_elt.uri == u'jabber:x:data' | |
58 schema_elt.addChild(x_elt) | |
59 return schema_elt | |
60 | |
61 def onSchemaGet(self, iq_elt): | |
62 try: | |
63 schema_elt = next(iq_elt.pubsub.elements(const.NS_SCHEMA, 'schema')) | |
64 nodeIdentifier = schema_elt['node'] | |
65 except StopIteration: | |
66 raise pubsub.BadRequest(text='missing schema element') | |
67 except KeyError: | |
68 raise pubsub.BadRequest(text='missing node') | |
69 pep = iq_elt.delegated | |
70 recipient = jid.JID(iq_elt['to']) | |
71 d = self.backend.getNodeSchema(nodeIdentifier, | |
72 pep, | |
73 recipient) | |
74 d.addCallback(self._getNodeSchemaCb, nodeIdentifier) | |
75 return d.addErrback(self.pubsub_service.resource._mapErrors) | |
76 | |
77 def onSchemaSet(self, iq_elt): | |
78 try: | |
79 schema_elt = next(iq_elt.pubsub.elements(const.NS_SCHEMA, 'schema')) | |
80 nodeIdentifier = schema_elt['node'] | |
81 except StopIteration: | |
82 raise pubsub.BadRequest(text='missing schema element') | |
83 except KeyError: | |
84 raise pubsub.BadRequest(text='missing node') | |
85 requestor = jid.JID(iq_elt['from']) | |
86 pep = iq_elt.delegated | |
87 recipient = jid.JID(iq_elt['to']) | |
361
a92f482ff14f
schema: allow free FORM_TYPE as this is used for items validation, and should not be in schema namespace
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
88 try: |
a92f482ff14f
schema: allow free FORM_TYPE as this is used for items validation, and should not be in schema namespace
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
89 x_elt = next(schema_elt.elements(data_form.NS_X_DATA, u'x')) |
a92f482ff14f
schema: allow free FORM_TYPE as this is used for items validation, and should not be in schema namespace
Goffi <goffi@goffi.org>
parents:
352
diff
changeset
|
90 except StopIteration: |
352 | 91 # no schema form has been found |
92 x_elt = None | |
93 d = self.backend.setNodeSchema(nodeIdentifier, | |
94 x_elt, | |
95 requestor, | |
96 pep, | |
97 recipient) | |
98 return d.addErrback(self.pubsub_service.resource._mapErrors) | |
99 | |
100 def getDiscoInfo(self, requestor, service, nodeIdentifier=''): | |
101 return [disco.DiscoFeature(const.NS_SCHEMA)] | |
102 | |
103 def getDiscoItems(self, requestor, service, nodeIdentifier=''): | |
104 return [] |