Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_misc_forums.py @ 4191:5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
- document the fact that if an empty `uri` is used, the forum node is created
automatically
- new `forums/set` CLI commands and its documentation
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 11 Dec 2023 18:10:27 +0100 |
parents | 4b842c1fb686 |
children | 1d24ff583794 |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
2484 | 3 |
2959
989b622faff6
plugins schema, tickets, merge_requests: use serialised data for extra dict + some cosmetic changes
Goffi <goffi@goffi.org>
parents:
2771
diff
changeset
|
4 # SAT plugin for pubsub forums |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2484 | 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 | |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
20 from typing import Iterable |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
21 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
|
22 from libervia.backend.core.i18n import _ |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
23 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
|
24 from libervia.backend.core import exceptions |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
25 from libervia.backend.core.log import getLogger |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
26 from libervia.backend.tools.common import uri, data_format |
2484 | 27 from twisted.words.protocols.jabber import jid |
28 from twisted.words.xish import domish | |
29 from twisted.internet import defer | |
30 import shortuuid | |
31 import json | |
32 log = getLogger(__name__) | |
33 | |
3028 | 34 NS_FORUMS = 'org.salut-a-toi.forums:0' |
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", | |
45 C.PI_DESCRIPTION: _("""forums management plugin""") | |
46 } | |
3028 | 47 FORUM_ATTR = {'title', 'name', 'main-language', 'uri'} |
48 FORUM_SUB_ELTS = ('short-desc', 'desc') | |
49 FORUM_TOPICS_NODE_TPL = '{node}#topics_{uuid}' | |
50 FORUM_TOPIC_NODE_TPL = '{node}_{uuid}' | |
2484 | 51 |
52 | |
53 class forums(object): | |
54 | |
55 def __init__(self, host): | |
3028 | 56 log.info(_("forums plugin initialization")) |
2484 | 57 self.host = host |
58 self._m = self.host.plugins['XEP-0277'] | |
59 self._p = self.host.plugins['XEP-0060'] | |
60 self._node_options = { | |
61 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, | |
62 self._p.OPT_PERSIST_ITEMS: 1, | |
63 self._p.OPT_DELIVER_PAYLOADS: 1, | |
64 self._p.OPT_SEND_ITEM_SUBSCRIBE: 1, | |
65 self._p.OPT_PUBLISH_MODEL: self._p.ACCESS_OPEN, | |
66 } | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
67 host.register_namespace('forums', NS_FORUMS) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
68 host.bridge.add_method("forums_get", ".plugin", |
2484 | 69 in_sign='ssss', out_sign='s', |
70 method=self._get, | |
3028 | 71 async_=True) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
72 host.bridge.add_method("forums_set", ".plugin", |
2484 | 73 in_sign='sssss', out_sign='', |
74 method=self._set, | |
3028 | 75 async_=True) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
76 host.bridge.add_method("forum_topics_get", ".plugin", |
3549
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
77 in_sign='ssa{ss}s', out_sign='(aa{ss}s)', |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
78 method=self._get_topics, |
3028 | 79 async_=True) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
80 host.bridge.add_method("forum_topic_create", ".plugin", |
2484 | 81 in_sign='ssa{ss}s', out_sign='', |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
82 method=self._create_topic, |
3028 | 83 async_=True) |
2484 | 84 |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
85 async def _create_forums( |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
86 self, |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
87 client: SatXMPPEntity, |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
88 forums: list[dict], |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
89 service: jid.JID, |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
90 node: str, |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
91 forums_elt: domish.Element|None = None, |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
92 names: Iterable = None |
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
93 ) -> 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
|
94 """Recursively create <forums> element(s) |
2484 | 95 |
96 @param forums(list): forums which may have subforums | |
97 @param service(jid.JID): service where the new nodes will be created | |
98 @param node(unicode): node of the forums | |
99 will be used as basis for the newly created nodes | |
100 @param parent_elt(domish.Element, None): element where the forum must be added | |
101 if None, the root <forums> element will be created | |
102 @return (domish.Element): created forums | |
103 """ | |
104 if not isinstance(forums, list): | |
3028 | 105 raise ValueError(_("forums arguments must be a list of forums")) |
2484 | 106 if forums_elt is None: |
3028 | 107 forums_elt = domish.Element((NS_FORUMS, 'forums')) |
2484 | 108 assert names is None |
109 names = set() | |
110 else: | |
3028 | 111 if names is None or forums_elt.name != 'forums': |
112 raise exceptions.InternalError('invalid forums or names') | |
2484 | 113 assert names is not None |
114 | |
115 for forum in forums: | |
116 if not isinstance(forum, dict): | |
3028 | 117 raise ValueError(_("A forum item must be a dictionary")) |
2484 | 118 forum_elt = forums_elt.addElement('forum') |
119 | |
3028 | 120 for key, value in forum.items(): |
121 if key == 'name' and key in names: | |
122 raise exceptions.ConflictError(_("following forum name is not unique: {name}").format(name=key)) | |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
123 if key == 'uri' and value is None or not value.strip(): |
3028 | 124 log.info(_("creating missing forum node")) |
2484 | 125 forum_node = FORUM_TOPICS_NODE_TPL.format(node=node, uuid=shortuuid.uuid()) |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
126 await self._p.createNode(client, service, forum_node, self._node_options) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
127 value = uri.build_xmpp_uri('pubsub', |
2484 | 128 path=service.full(), |
129 node=forum_node) | |
130 if key in FORUM_ATTR: | |
131 forum_elt[key] = value.strip() | |
132 elif key in FORUM_SUB_ELTS: | |
133 forum_elt.addElement(key, content=value) | |
3028 | 134 elif key == 'sub-forums': |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
135 assert isinstance(value, list) |
3028 | 136 sub_forums_elt = forum_elt.addElement('forums') |
4191
5d056d524298
core, doc, cli (forums): new `forums set` commands + doc:
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
137 await self._create_forums(client, value, service, node, sub_forums_elt, names=names) |
2484 | 138 else: |
3028 | 139 log.warning(_("Unknown forum attribute: {key}").format(key=key)) |
140 if not forum_elt.getAttribute('title'): | |
141 name = forum_elt.getAttribute('name') | |
2484 | 142 if name: |
3028 | 143 forum_elt['title'] = name |
2484 | 144 else: |
3028 | 145 raise ValueError(_("forum need a title or a name")) |
146 if not forum_elt.getAttribute('uri') and not forum_elt.children: | |
147 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
|
148 return forums_elt |
2484 | 149 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
150 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
|
151 """Recursivly parse a <forums> elements and return corresponding forums data |
2484 | 152 |
153 @param item(domish.Element): item with <forums> element | |
154 @param parent_elt(domish.Element, None): element to parse | |
155 @return (list): parsed data | |
156 @raise ValueError: item is invalid | |
157 """ | |
3028 | 158 if parent_elt.name == 'item': |
2484 | 159 forums = [] |
160 try: | |
3028 | 161 forums_elt = next(parent_elt.elements(NS_FORUMS, 'forums')) |
2484 | 162 except StopIteration: |
3028 | 163 raise ValueError(_("missing <forums> element")) |
2484 | 164 else: |
165 forums_elt = parent_elt | |
166 if forums is None: | |
3028 | 167 raise exceptions.InternalError('expected forums') |
2484 | 168 if forums_elt.name != 'forums': |
3028 | 169 raise ValueError(_('Unexpected element: {xml}').format(xml=forums_elt.toXml())) |
2484 | 170 for forum_elt in forums_elt.elements(): |
171 if forum_elt.name == 'forum': | |
172 data = {} | |
173 for attrib in FORUM_ATTR.intersection(forum_elt.attributes): | |
174 data[attrib] = forum_elt[attrib] | |
175 unknown = set(forum_elt.attributes).difference(FORUM_ATTR) | |
176 if unknown: | |
3028 | 177 log.warning(_("Following attributes are unknown: {unknown}").format(unknown=unknown)) |
2484 | 178 for elt in forum_elt.elements(): |
179 if elt.name in FORUM_SUB_ELTS: | |
3028 | 180 data[elt.name] = str(elt) |
181 elif elt.name == 'forums': | |
182 sub_forums = data['sub-forums'] = [] | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
183 self._parse_forums(elt, sub_forums) |
3028 | 184 if not 'title' in data or not {'uri', 'sub-forums'}.intersection(data): |
185 log.warning(_("invalid forum, ignoring: {xml}").format(xml=forum_elt.toXml())) | |
2484 | 186 else: |
187 forums.append(data) | |
188 else: | |
3028 | 189 log.warning(_("unkown forums sub element: {xml}").format(xml=forum_elt)) |
2484 | 190 |
191 return forums | |
192 | |
193 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
|
194 client = self.host.get_client(profile_key) |
2484 | 195 if service.strip(): |
196 service = jid.JID(service) | |
197 else: | |
198 service = None | |
199 if not node.strip(): | |
200 node = None | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
201 d = defer.ensureDeferred(self.get(client, service, node, forums_key or None)) |
2484 | 202 d.addCallback(lambda data: json.dumps(data)) |
203 return d | |
204 | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
205 async def get(self, client, service=None, node=None, forums_key=None): |
2484 | 206 if service is None: |
207 service = client.pubsub_service | |
208 if node is None: | |
209 node = NS_FORUMS | |
210 if forums_key is None: | |
3028 | 211 forums_key = 'default' |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
212 items_data = await self._p.get_items(client, service, node, item_ids=[forums_key]) |
2484 | 213 item = items_data[0][0] |
214 # 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
|
215 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
|
216 return forums |
2484 | 217 |
218 def _set(self, forums, 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
|
219 client = self.host.get_client(profile_key) |
2484 | 220 forums = json.loads(forums) |
221 if service.strip(): | |
222 service = jid.JID(service) | |
223 else: | |
224 service = None | |
225 if not node.strip(): | |
226 node = None | |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
227 return defer.ensureDeferred( |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
228 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
|
229 ) |
2484 | 230 |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
231 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
|
232 """Create or replace forums structure |
2484 | 233 |
234 @param forums(list): list of dictionary as follow: | |
235 a dictionary represent a forum metadata, with the following keys: | |
236 - title: title of the forum | |
237 - name: short name (unique in those forums) for the forum | |
238 - main-language: main language to be use in the forums | |
239 - uri: XMPP uri to the microblog node hosting the forum | |
240 - short-desc: short description of the forum (in main-language) | |
241 - desc: long description of the forum (in main-language) | |
242 - sub-forums: a list of sub-forums with the same structure | |
243 title or name is needed, and uri or sub-forums | |
244 @param forums_key(unicode, None): key (i.e. item id) of the forums | |
245 may be used to store different forums structures for different languages | |
246 None to use "default" | |
247 """ | |
248 if service is None: | |
249 service = client.pubsub_service | |
250 if node is None: | |
251 node = NS_FORUMS | |
252 if forums_key is None: | |
3028 | 253 forums_key = 'default' |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
254 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
|
255 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
|
256 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
|
257 ) |
2484 | 258 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
259 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
|
260 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
|
261 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
|
262 d = defer.ensureDeferred( |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
263 self.get_topics( |
3584
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
264 client, jid.JID(service), node, rsm_request=extra.rsm_request, |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
265 extra=extra.extra |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
266 ) |
edc79cefe968
plugin XEP-0060: `getItem(s)`, `publish` and `(un)subscribe` are now coroutines
Goffi <goffi@goffi.org>
parents:
3549
diff
changeset
|
267 ) |
3549
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
268 d.addCallback( |
3fd60beb9b92
plugin forums: use serialised data for extra in forumTopicsGet
Goffi <goffi@goffi.org>
parents:
3515
diff
changeset
|
269 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
|
270 ) |
2484 | 271 return d |
272 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
273 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
|
274 """Retrieve topics data |
2484 | 275 |
276 Topics are simple microblog URIs with some metadata duplicated from first post | |
277 """ | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
278 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
|
279 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
|
280 ) |
2484 | 281 topics = [] |
282 item_elts, metadata = topics_data | |
283 for item_elt in item_elts: | |
3028 | 284 topic_elt = next(item_elt.elements(NS_FORUMS, 'topic')) |
285 title_elt = next(topic_elt.elements(NS_FORUMS, 'title')) | |
286 topic = {'uri': topic_elt['uri'], | |
287 'author': topic_elt['author'], | |
288 'title': str(title_elt)} | |
2484 | 289 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
|
290 return (topics, metadata) |
2484 | 291 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
292 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
|
293 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
|
294 return defer.ensureDeferred( |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
295 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
|
296 ) |
2484 | 297 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
298 async def create_topic(self, client, service, node, mb_data): |
2484 | 299 try: |
3028 | 300 title = mb_data['title'] |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
301 content = mb_data.pop('content') |
2484 | 302 except KeyError as e: |
3028 | 303 raise exceptions.DataError("missing mandatory data: {key}".format(key=e.args[0])) |
3515
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
304 else: |
2dce411c2647
plugin misc forums: use rich content in createTopic
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
305 mb_data["content_rich"] = content |
2484 | 306 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
|
307 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
|
308 await self._m.send(client, mb_data, service, topic_node) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3931
diff
changeset
|
309 topic_uri = uri.build_xmpp_uri('pubsub', |
3028 | 310 subtype='microblog', |
2484 | 311 path=service.full(), |
312 node=topic_node) | |
313 topic_elt = domish.Element((NS_FORUMS, 'topic')) | |
3028 | 314 topic_elt['uri'] = topic_uri |
315 topic_elt['author'] = client.jid.userhost() | |
316 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
|
317 await self._p.send_item(client, service, node, topic_elt) |