Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_misc_forums.py @ 4294:a0ed5c976bf8 default tip @
component conferences, plugin XEP-0167, XEP-0298: add stream user metadata:
A/V conference now adds user metadata about the stream it is forwarding through XEP-0298.
This is parsed and added to metadata during confirmation on client side.
rel 448
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 06 Aug 2024 23:43:11 +0200 |
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) |