Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_misc_forums.py @ 4351:6a0a081485b8
plugin autocrypt: Autocrypt protocol implementation:
Implementation of autocrypt: `autocrypt` header is checked, and if present and no public
key is known for the peer, the key is imported.
`autocrypt` header is also added to outgoing message (only if an email gateway is
detected).
For the moment, the JID is use as identifier, but the real email used by gateway should be
used in the future.
rel 456
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 28 Feb 2025 09:23:35 +0100 |
parents | 1d24ff583794 |
children |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
3 # Libervia plugin for pubsub forums |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org) |
2484 | 5 |
6 # This program is free software: you can redistribute it and/or modify | |
7 # it under the terms of the GNU Affero General Public License as published by | |
8 # the Free Software Foundation, either version 3 of the License, or | |
9 # (at your option) any later version. | |
10 | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU Affero General Public License for more details. | |
15 | |
16 # You should have received a copy of the GNU Affero General Public License | |
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
19 from typing import Iterable |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
20 from libervia.backend.core.core_types import SatXMPPEntity |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
21 from libervia.backend.core.i18n import _ |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
22 from libervia.backend.core.constants import Const as C |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
23 from libervia.backend.core import exceptions |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
24 from libervia.backend.core.log import getLogger |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
25 from libervia.backend.tools.common import uri, data_format |
2484 | 26 from twisted.words.protocols.jabber import jid |
27 from twisted.words.xish import domish | |
28 from twisted.internet import defer | |
29 import shortuuid | |
30 import json | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
31 |
2484 | 32 log = getLogger(__name__) |
33 | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
34 NS_FORUMS = "org.salut-a-toi.forums:0" |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
35 NS_FORUMS_TOPICS = NS_FORUMS + "#topics" |
2484 | 36 |
37 PLUGIN_INFO = { | |
38 C.PI_NAME: _("forums management"), | |
39 C.PI_IMPORT_NAME: "forums", | |
40 C.PI_TYPE: "EXP", | |
41 C.PI_PROTOCOLS: [], | |
42 C.PI_DEPENDENCIES: ["XEP-0060", "XEP-0277"], | |
43 C.PI_MAIN: "forums", | |
44 C.PI_HANDLER: "no", | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
45 C.PI_DESCRIPTION: _("""forums management plugin"""), |
2484 | 46 } |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
47 FORUM_ATTR = {"title", "name", "main-language", "uri"} |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
48 FORUM_SUB_ELTS = ("short-desc", "desc") |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
49 FORUM_TOPICS_NODE_TPL = "{node}#topics_{uuid}" |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
50 FORUM_TOPIC_NODE_TPL = "{node}_{uuid}" |
2484 | 51 |
52 | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
53 class forums: |
2484 | 54 def __init__(self, host): |
3028 | 55 log.info(_("forums plugin initialization")) |
2484 | 56 self.host = host |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
57 self._m = self.host.plugins["XEP-0277"] |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
58 self._p = self.host.plugins["XEP-0060"] |
2484 | 59 self._node_options = { |
60 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, | |
61 self._p.OPT_PERSIST_ITEMS: 1, | |
62 self._p.OPT_DELIVER_PAYLOADS: 1, | |
63 self._p.OPT_SEND_ITEM_SUBSCRIBE: 1, | |
64 self._p.OPT_PUBLISH_MODEL: self._p.ACCESS_OPEN, | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
65 } |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
66 host.register_namespace("forums", NS_FORUMS) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
67 host.bridge.add_method( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
68 "forums_get", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
69 ".plugin", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
70 in_sign="ssss", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
71 out_sign="s", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
72 method=self._get, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
73 async_=True, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
74 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
75 host.bridge.add_method( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
76 "forums_set", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
77 ".plugin", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
78 in_sign="sssss", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
79 out_sign="", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
80 method=self._set, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
81 async_=True, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
82 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
83 host.bridge.add_method( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
84 "forum_topics_get", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
85 ".plugin", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
86 in_sign="ssa{ss}s", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
87 out_sign="(aa{ss}s)", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
88 method=self._get_topics, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
89 async_=True, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
90 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
91 host.bridge.add_method( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
92 "forum_topic_create", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
93 ".plugin", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
94 in_sign="ssa{ss}s", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
95 out_sign="", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
96 method=self._create_topic, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
97 async_=True, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
98 ) |
2484 | 99 |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
100 async def _create_forums( |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
101 self, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
102 client: SatXMPPEntity, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
103 forums: list[dict], |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
104 service: jid.JID, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
105 node: str, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
106 forums_elt: domish.Element | None = None, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
107 names: Iterable = None, |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
108 ) -> domish.Element: |
2959
989b622faff6
plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
109 """Recursively create <forums> element(s) |
2484 | 110 |
111 @param forums(list): forums which may have subforums | |
112 @param service(jid.JID): service where the new nodes will be created | |
113 @param node(unicode): node of the forums | |
114 will be used as basis for the newly created nodes | |
115 @param parent_elt(domish.Element, None): element where the forum must be added | |
116 if None, the root <forums> element will be created | |
117 @return (domish.Element): created forums | |
118 """ | |
119 if not isinstance(forums, list): | |
3028 | 120 raise ValueError(_("forums arguments must be a list of forums")) |
2484 | 121 if forums_elt is None: |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
122 forums_elt = domish.Element((NS_FORUMS, "forums")) |
2484 | 123 assert names is None |
124 names = set() | |
125 else: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
126 if names is None or forums_elt.name != "forums": |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
127 raise exceptions.InternalError("invalid forums or names") |
2484 | 128 assert names is not None |
129 | |
130 for forum in forums: | |
131 if not isinstance(forum, dict): | |
3028 | 132 raise ValueError(_("A forum item must be a dictionary")) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
133 forum_elt = forums_elt.addElement("forum") |
2484 | 134 |
3028 | 135 for key, value in forum.items(): |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
136 if key == "name" and key in names: |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
137 raise exceptions.ConflictError( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
138 _("following forum name is not unique: {name}").format(name=key) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
139 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
140 if key == "uri" and (value is None or not value.strip()): |
3028 | 141 log.info(_("creating missing forum node")) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
142 forum_node = FORUM_TOPICS_NODE_TPL.format( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
143 node=node, uuid=shortuuid.uuid() |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
144 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
145 await self._p.createNode( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
146 client, service, forum_node, self._node_options |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
147 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
148 value = uri.build_xmpp_uri( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
149 "pubsub", path=service.full(), node=forum_node |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
150 ) |
2484 | 151 if key in FORUM_ATTR: |
152 forum_elt[key] = value.strip() | |
153 elif key in FORUM_SUB_ELTS: | |
154 forum_elt.addElement(key, content=value) | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
155 elif key == "sub-forums": |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
156 assert isinstance(value, list) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
157 sub_forums_elt = forum_elt.addElement("forums") |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
158 await self._create_forums( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
159 client, value, service, node, sub_forums_elt, names=names |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
160 ) |
2484 | 161 else: |
3028 | 162 log.warning(_("Unknown forum attribute: {key}").format(key=key)) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
163 if not forum_elt.getAttribute("title"): |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
164 name = forum_elt.getAttribute("name") |
2484 | 165 if name: |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
166 forum_elt["title"] = name |
2484 | 167 else: |
3028 | 168 raise ValueError(_("forum need a title or a name")) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
169 if not forum_elt.getAttribute("uri") and not forum_elt.children: |
3028 | 170 raise ValueError(_("forum need uri or sub-forums")) |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
171 return forums_elt |
2484 | 172 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
173 def _parse_forums(self, parent_elt=None, forums=None): |
2959
989b622faff6
plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
174 """Recursivly parse a <forums> elements and return corresponding forums data |
2484 | 175 |
176 @param item(domish.Element): item with <forums> element | |
177 @param parent_elt(domish.Element, None): element to parse | |
178 @return (list): parsed data | |
179 @raise ValueError: item is invalid | |
180 """ | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
181 if parent_elt.name == "item": |
2484 | 182 forums = [] |
183 try: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
184 forums_elt = next(parent_elt.elements(NS_FORUMS, "forums")) |
2484 | 185 except StopIteration: |
3028 | 186 raise ValueError(_("missing <forums> element")) |
2484 | 187 else: |
188 forums_elt = parent_elt | |
189 if forums is None: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
190 raise exceptions.InternalError("expected forums") |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
191 if forums_elt.name != "forums": |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
192 raise ValueError( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
193 _("Unexpected element: {xml}").format(xml=forums_elt.toXml()) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
194 ) |
2484 | 195 for forum_elt in forums_elt.elements(): |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
196 if forum_elt.name == "forum": |
2484 | 197 data = {} |
198 for attrib in FORUM_ATTR.intersection(forum_elt.attributes): | |
199 data[attrib] = forum_elt[attrib] | |
200 unknown = set(forum_elt.attributes).difference(FORUM_ATTR) | |
201 if unknown: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
202 log.warning( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
203 _("Following attributes are unknown: {unknown}").format( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
204 unknown=unknown |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
205 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
206 ) |
2484 | 207 for elt in forum_elt.elements(): |
208 if elt.name in FORUM_SUB_ELTS: | |
3028 | 209 data[elt.name] = str(elt) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
210 elif elt.name == "forums": |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
211 sub_forums = data["sub-forums"] = [] |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
212 self._parse_forums(elt, sub_forums) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
213 if not "title" in data or not {"uri", "sub-forums"}.intersection(data): |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
214 log.warning( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
215 _("invalid forum, ignoring: {xml}").format(xml=forum_elt.toXml()) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
216 ) |
2484 | 217 else: |
218 forums.append(data) | |
219 else: | |
3028 | 220 log.warning(_("unkown forums sub element: {xml}").format(xml=forum_elt)) |
2484 | 221 |
222 return forums | |
223 | |
224 def _get(self, service=None, node=None, forums_key=None, profile_key=C.PROF_KEY_NONE): | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
225 client = self.host.get_client(profile_key) |
2484 | 226 if service.strip(): |
227 service = jid.JID(service) | |
228 else: | |
229 service = None | |
230 if not node.strip(): | |
231 node = None | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
232 d = defer.ensureDeferred(self.get(client, service, node, forums_key or None)) |
2484 | 233 d.addCallback(lambda data: json.dumps(data)) |
234 return d | |
235 | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
236 async def get(self, client, service=None, node=None, forums_key=None): |
2484 | 237 if service is None: |
238 service = client.pubsub_service | |
239 if node is None: | |
240 node = NS_FORUMS | |
241 if forums_key is None: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
242 forums_key = "default" |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
243 items_data = await self._p.get_items(client, service, node, item_ids=[forums_key]) |
2484 | 244 item = items_data[0][0] |
245 # we have the item and need to convert it to json | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
246 forums = self._parse_forums(item) |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
247 return forums |
2484 | 248 |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
249 def _set( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
250 self, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
251 forums: str, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
252 service_s: str = "", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
253 node_s: str = "", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
254 forums_key: str = "", |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
255 profile_key: str = C.PROF_KEY_NONE, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
256 ) -> defer.Deferred: |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
257 client = self.host.get_client(profile_key) |
2484 | 258 forums = json.loads(forums) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
259 if not service_s.strip(): |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
260 service = None |
2484 | 261 else: |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
262 service = jid.JID(service_s) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
263 node = None if not node_s.strip() else node_s |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
264 return defer.ensureDeferred( |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
265 self.set(client, forums, service, node, forums_key or None) |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
266 ) |
2484 | 267 |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
268 async def set(self, client, forums, service=None, node=None, forums_key=None): |
2959
989b622faff6
plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
269 """Create or replace forums structure |
2484 | 270 |
271 @param forums(list): list of dictionary as follow: | |
272 a dictionary represent a forum metadata, with the following keys: | |
273 - title: title of the forum | |
274 - name: short name (unique in those forums) for the forum | |
275 - main-language: main language to be use in the forums | |
276 - uri: XMPP uri to the microblog node hosting the forum | |
277 - short-desc: short description of the forum (in main-language) | |
278 - desc: long description of the forum (in main-language) | |
279 - sub-forums: a list of sub-forums with the same structure | |
280 title or name is needed, and uri or sub-forums | |
281 @param forums_key(unicode, None): key (i.e. item id) of the forums | |
282 may be used to store different forums structures for different languages | |
283 None to use "default" | |
284 """ | |
285 if service is None: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
286 service = client.pubsub_service |
2484 | 287 if node is None: |
288 node = NS_FORUMS | |
289 if forums_key is None: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
290 forums_key = "default" |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
291 forums_elt = await self._create_forums(client, forums, service, node) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
292 return await self._p.send_item( |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
293 client, service, node, forums_elt, item_id=forums_key |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
294 ) |
2484 | 295 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
296 def _get_topics(self, service, node, extra=None, profile_key=C.PROF_KEY_NONE): |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
297 client = self.host.get_client(profile_key) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
298 extra = self._p.parse_extra(extra) |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
299 d = defer.ensureDeferred( |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
300 self.get_topics( |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
301 client, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
302 jid.JID(service), |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
303 node, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
304 rsm_request=extra.rsm_request, |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
305 extra=extra.extra, |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
306 ) |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
307 ) |
3549
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
308 d.addCallback( |
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
309 lambda topics_data: (topics_data[0], data_format.serialise(topics_data[1])) |
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
310 ) |
2484 | 311 return d |
312 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
313 async def get_topics(self, client, service, node, rsm_request=None, extra=None): |
2959
989b622faff6
plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
314 """Retrieve topics data |
2484 | 315 |
316 Topics are simple microblog URIs with some metadata duplicated from first post | |
317 """ | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
318 topics_data = await self._p.get_items( |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
319 client, service, node, rsm_request=rsm_request, extra=extra |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
320 ) |
2484 | 321 topics = [] |
322 item_elts, metadata = topics_data | |
323 for item_elt in item_elts: | |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
324 topic_elt = next(item_elt.elements(NS_FORUMS, "topic")) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
325 title_elt = next(topic_elt.elements(NS_FORUMS, "title")) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
326 topic = { |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
327 "uri": topic_elt["uri"], |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
328 "author": topic_elt["author"], |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
329 "title": str(title_elt), |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
330 } |
2484 | 331 topics.append(topic) |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
332 return (topics, metadata) |
2484 | 333 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
334 def _create_topic(self, service, node, mb_data, profile_key): |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
335 client = self.host.get_client(profile_key) |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
336 return defer.ensureDeferred( |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
337 self.create_topic(client, jid.JID(service), node, mb_data) |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
338 ) |
2484 | 339 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
340 async def create_topic(self, client, service, node, mb_data): |
2484 | 341 try: |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
342 title = mb_data["title"] |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
343 content = mb_data.pop("content") |
2484 | 344 except KeyError as e: |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
345 raise exceptions.DataError( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
346 "missing mandatory data: {key}".format(key=e.args[0]) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
347 ) |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
348 else: |
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
349 mb_data["content_rich"] = content |
2484 | 350 topic_node = FORUM_TOPIC_NODE_TPL.format(node=node, uuid=shortuuid.uuid()) |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
351 await self._p.createNode(client, service, topic_node, self._node_options) |
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
352 await self._m.send(client, mb_data, service, topic_node) |
4192
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
353 topic_uri = uri.build_xmpp_uri( |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
354 "pubsub", subtype="microblog", path=service.full(), node=topic_node |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
355 ) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
356 topic_elt = domish.Element((NS_FORUMS, "topic")) |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
357 topic_elt["uri"] = topic_uri |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
358 topic_elt["author"] = client.jid.userhost() |
1d24ff583794
plugin forums: parsing fix + formatting:
Goffi <goffi@goffi.org>
parents:
4191
diff
changeset
|
359 topic_elt.addElement("title", content=title) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
360 await self._p.send_item(client, service, node, topic_elt) |