Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_exp_invitation.py @ 4270:0d7bb4df2343
Reformatted code base using black.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 19 Jun 2024 18:44:57 +0200 |
parents | 4b842c1fb686 |
children |
comparison
equal
deleted
inserted
replaced
4269:64a85ce8be70 | 4270:0d7bb4df2343 |
---|---|
43 C.PI_HANDLER: "yes", | 43 C.PI_HANDLER: "yes", |
44 C.PI_DESCRIPTION: _("Experimental handling of invitations"), | 44 C.PI_DESCRIPTION: _("Experimental handling of invitations"), |
45 } | 45 } |
46 | 46 |
47 NS_INVITATION = "https://salut-a-toi/protocol/invitation:0" | 47 NS_INVITATION = "https://salut-a-toi/protocol/invitation:0" |
48 INVITATION = '/message/invitation[@xmlns="{ns_invit}"]'.format( | 48 INVITATION = '/message/invitation[@xmlns="{ns_invit}"]'.format(ns_invit=NS_INVITATION) |
49 ns_invit=NS_INVITATION | |
50 ) | |
51 NS_INVITATION_LIST = NS_INVITATION + "#list" | 49 NS_INVITATION_LIST = NS_INVITATION + "#list" |
52 | 50 |
53 | 51 |
54 class Invitation(object): | 52 class Invitation(object): |
55 | 53 |
89 - path(unicode, None): path of the repository | 87 - path(unicode, None): path of the repository |
90 @raise exceptions.ConflictError: this namespace is already registered | 88 @raise exceptions.ConflictError: this namespace is already registered |
91 """ | 89 """ |
92 if namespace in self._ns_cb: | 90 if namespace in self._ns_cb: |
93 raise exceptions.ConflictError( | 91 raise exceptions.ConflictError( |
94 "invitation namespace {namespace} is already register with {callback}" | 92 "invitation namespace {namespace} is already register with {callback}".format( |
95 .format(namespace=namespace, callback=self._ns_cb[namespace])) | 93 namespace=namespace, callback=self._ns_cb[namespace] |
94 ) | |
95 ) | |
96 self._ns_cb[namespace] = callback | 96 self._ns_cb[namespace] = callback |
97 | 97 |
98 def _generate_base_invitation(self, client, invitee_jid, name, extra): | 98 def _generate_base_invitation(self, client, invitee_jid, name, extra): |
99 """Generate common mess_data end invitation_elt | 99 """Generate common mess_data end invitation_elt |
100 | 100 |
116 client.generate_message_xml(mess_data) | 116 client.generate_message_xml(mess_data) |
117 self._h.add_hint_elements(mess_data["xml"], [self._h.HINT_STORE]) | 117 self._h.add_hint_elements(mess_data["xml"], [self._h.HINT_STORE]) |
118 invitation_elt = mess_data["xml"].addElement("invitation", NS_INVITATION) | 118 invitation_elt = mess_data["xml"].addElement("invitation", NS_INVITATION) |
119 if name is not None: | 119 if name is not None: |
120 invitation_elt["name"] = name | 120 invitation_elt["name"] = name |
121 thumb_url = extra.get('thumb_url') | 121 thumb_url = extra.get("thumb_url") |
122 if thumb_url: | 122 if thumb_url: |
123 if not thumb_url.startswith('http'): | 123 if not thumb_url.startswith("http"): |
124 log.warning( | 124 log.warning( |
125 "only http URLs are allowed for thumbnails, got {url}, ignoring" | 125 "only http URLs are allowed for thumbnails, got {url}, ignoring".format( |
126 .format(url=thumb_url)) | 126 url=thumb_url |
127 ) | |
128 ) | |
127 else: | 129 else: |
128 invitation_elt['thumb_url'] = thumb_url | 130 invitation_elt["thumb_url"] = thumb_url |
129 return mess_data, invitation_elt | 131 return mess_data, invitation_elt |
130 | 132 |
131 def send_pubsub_invitation( | 133 def send_pubsub_invitation( |
132 self, | 134 self, |
133 client: SatXMPPEntity, | 135 client: SatXMPPEntity, |
134 invitee_jid: jid.JID, | 136 invitee_jid: jid.JID, |
135 service: jid.JID, | 137 service: jid.JID, |
136 node: str, | 138 node: str, |
137 item_id: Optional[str], | 139 item_id: Optional[str], |
138 name: Optional[str], | 140 name: Optional[str], |
139 extra: Optional[dict] | 141 extra: Optional[dict], |
140 ) -> None: | 142 ) -> None: |
141 """Send an pubsub invitation in a <message> stanza | 143 """Send an pubsub invitation in a <message> stanza |
142 | 144 |
143 @param invitee_jid: entitee to send invitation to | 145 @param invitee_jid: entitee to send invitation to |
144 @param service: pubsub service | 146 @param service: pubsub service |
149 @param extra: see [_generate_base_invitation] | 151 @param extra: see [_generate_base_invitation] |
150 """ | 152 """ |
151 if extra is None: | 153 if extra is None: |
152 extra = {} | 154 extra = {} |
153 mess_data, invitation_elt = self._generate_base_invitation( | 155 mess_data, invitation_elt = self._generate_base_invitation( |
154 client, invitee_jid, name, extra) | 156 client, invitee_jid, name, extra |
157 ) | |
155 pubsub_elt = invitation_elt.addElement("pubsub") | 158 pubsub_elt = invitation_elt.addElement("pubsub") |
156 pubsub_elt["service"] = service.full() | 159 pubsub_elt["service"] = service.full() |
157 pubsub_elt["node"] = node | 160 pubsub_elt["node"] = node |
158 if item_id is None: | 161 if item_id is None: |
159 try: | 162 try: |
171 if "element" in extra: | 174 if "element" in extra: |
172 invitation_elt.addChild(extra.pop("element")) | 175 invitation_elt.addChild(extra.pop("element")) |
173 client.send(mess_data["xml"]) | 176 client.send(mess_data["xml"]) |
174 | 177 |
175 async def send_file_sharing_invitation( | 178 async def send_file_sharing_invitation( |
176 self, client, invitee_jid, service, repos_type=None, namespace=None, path=None, | 179 self, |
177 name=None, extra=None | 180 client, |
181 invitee_jid, | |
182 service, | |
183 repos_type=None, | |
184 namespace=None, | |
185 path=None, | |
186 name=None, | |
187 extra=None, | |
178 ): | 188 ): |
179 """Send a file sharing invitation in a <message> stanza | 189 """Send a file sharing invitation in a <message> stanza |
180 | 190 |
181 @param invitee_jid(jid.JID): entitee to send invitation to | 191 @param invitee_jid(jid.JID): entitee to send invitation to |
182 @param service(jid.JID): file sharing service | 192 @param service(jid.JID): file sharing service |
194 li_plg.normalise_file_sharing_service(client, service) | 204 li_plg.normalise_file_sharing_service(client, service) |
195 | 205 |
196 # FIXME: not the best place to adapt permission, but it's necessary to check them | 206 # FIXME: not the best place to adapt permission, but it's necessary to check them |
197 # for UX | 207 # for UX |
198 try: | 208 try: |
199 await self.host.plugins['XEP-0329'].affiliationsSet( | 209 await self.host.plugins["XEP-0329"].affiliationsSet( |
200 client, service, namespace, path, {invitee_jid: "member"} | 210 client, service, namespace, path, {invitee_jid: "member"} |
201 ) | 211 ) |
202 except Exception as e: | 212 except Exception as e: |
203 log.warning(f"Can't set affiliation: {e}") | 213 log.warning(f"Can't set affiliation: {e}") |
204 | 214 |
212 "no thumbnail found for file sharing interest at " | 222 "no thumbnail found for file sharing interest at " |
213 f"[{service}/{namespace}]{path}" | 223 f"[{service}/{namespace}]{path}" |
214 ) | 224 ) |
215 else: | 225 else: |
216 try: | 226 try: |
217 extra['thumb_url'] = own_interest['thumb_url'] | 227 extra["thumb_url"] = own_interest["thumb_url"] |
218 except KeyError: | 228 except KeyError: |
219 pass | 229 pass |
220 | 230 |
221 mess_data, invitation_elt = self._generate_base_invitation( | 231 mess_data, invitation_elt = self._generate_base_invitation( |
222 client, invitee_jid, name, extra) | 232 client, invitee_jid, name, extra |
233 ) | |
223 file_sharing_elt = invitation_elt.addElement("file_sharing") | 234 file_sharing_elt = invitation_elt.addElement("file_sharing") |
224 file_sharing_elt["service"] = service.full() | 235 file_sharing_elt["service"] = service.full() |
225 if repos_type is not None: | 236 if repos_type is not None: |
226 if repos_type not in ("files", "photos"): | 237 if repos_type not in ("files", "photos"): |
227 msg = "unknown repository type: {repos_type}".format( | 238 msg = "unknown repository type: {repos_type}".format( |
228 repos_type=repos_type) | 239 repos_type=repos_type |
240 ) | |
229 log.warning(msg) | 241 log.warning(msg) |
230 raise exceptions.DateError(msg) | 242 raise exceptions.DateError(msg) |
231 file_sharing_elt["type"] = repos_type | 243 file_sharing_elt["type"] = repos_type |
232 if namespace is not None: | 244 if namespace is not None: |
233 file_sharing_elt["namespace"] = namespace | 245 file_sharing_elt["namespace"] = namespace |
248 try: | 260 try: |
249 items, metadata = await self._p.get_items( | 261 items, metadata = await self._p.get_items( |
250 client, service, node, item_ids=[item_id] | 262 client, service, node, item_ids=[item_id] |
251 ) | 263 ) |
252 except Exception as e: | 264 except Exception as e: |
253 log.warning(_("Can't get item linked with invitation: {reason}").format( | 265 log.warning( |
254 reason=e)) | 266 _("Can't get item linked with invitation: {reason}").format(reason=e) |
267 ) | |
255 try: | 268 try: |
256 item_elt = items[0] | 269 item_elt = items[0] |
257 except IndexError: | 270 except IndexError: |
258 log.warning(_("Invitation was linking to a non existing item")) | 271 log.warning(_("Invitation was linking to a non existing item")) |
259 raise exceptions.DataError | 272 raise exceptions.DataError |
260 | 273 |
261 try: | 274 try: |
262 namespace = item_elt.firstChildElement().uri | 275 namespace = item_elt.firstChildElement().uri |
263 except Exception as e: | 276 except Exception as e: |
264 log.warning(_("Can't retrieve namespace of invitation: {reason}").format( | 277 log.warning( |
265 reason = e)) | 278 _("Can't retrieve namespace of invitation: {reason}").format(reason=e) |
279 ) | |
266 raise exceptions.DataError | 280 raise exceptions.DataError |
267 | 281 |
268 args = [service, node, item_id, item_elt] | 282 args = [service, node, item_id, item_elt] |
269 else: | 283 else: |
270 try: | 284 try: |
271 node_data_elt = next(pubsub_elt.elements(NS_INVITATION, "node_data")) | 285 node_data_elt = next(pubsub_elt.elements(NS_INVITATION, "node_data")) |
272 except StopIteration: | 286 except StopIteration: |
273 raise exceptions.DataError("Bad invitation, ignoring") | 287 raise exceptions.DataError("Bad invitation, ignoring") |
274 namespace = node_data_elt['namespace'] | 288 namespace = node_data_elt["namespace"] |
275 args = [service, node, None, node_data_elt] | 289 args = [service, node, None, node_data_elt] |
276 | 290 |
277 return namespace, args | 291 return namespace, args |
278 | 292 |
279 async def _parse_file_sharing_elt(self, client, file_sharing_elt): | 293 async def _parse_file_sharing_elt(self, client, file_sharing_elt): |
294 invitation_elt = message_elt.invitation | 308 invitation_elt = message_elt.invitation |
295 | 309 |
296 name = invitation_elt.getAttribute("name") | 310 name = invitation_elt.getAttribute("name") |
297 extra = {} | 311 extra = {} |
298 if invitation_elt.hasAttribute("thumb_url"): | 312 if invitation_elt.hasAttribute("thumb_url"): |
299 extra['thumb_url'] = invitation_elt['thumb_url'] | 313 extra["thumb_url"] = invitation_elt["thumb_url"] |
300 | 314 |
301 for elt in invitation_elt.elements(): | 315 for elt in invitation_elt.elements(): |
302 if elt.uri != NS_INVITATION: | 316 if elt.uri != NS_INVITATION: |
303 log.warning("unexpected element: {xml}".format(xml=elt.toXml())) | 317 log.warning("unexpected element: {xml}".format(xml=elt.toXml())) |
304 continue | 318 continue |
305 if elt.name == "pubsub": | 319 if elt.name == "pubsub": |
306 method = self._parse_pubsub_elt | 320 method = self._parse_pubsub_elt |
307 elif elt.name == "file_sharing": | 321 elif elt.name == "file_sharing": |
308 method = self._parse_file_sharing_elt | 322 method = self._parse_file_sharing_elt |
309 else: | 323 else: |
310 log.warning("not implemented invitation element: {xml}".format( | 324 log.warning( |
311 xml = elt.toXml())) | 325 "not implemented invitation element: {xml}".format(xml=elt.toXml()) |
326 ) | |
312 continue | 327 continue |
313 try: | 328 try: |
314 namespace, args = await method(client, elt) | 329 namespace, args = await method(client, elt) |
315 except exceptions.DataError: | 330 except exceptions.DataError: |
316 log.warning("Can't parse invitation element: {xml}".format( | 331 log.warning( |
317 xml = elt.toXml())) | 332 "Can't parse invitation element: {xml}".format(xml=elt.toXml()) |
333 ) | |
318 continue | 334 continue |
319 | 335 |
320 try: | 336 try: |
321 cb = self._ns_cb[namespace] | 337 cb = self._ns_cb[namespace] |
322 except KeyError: | 338 except KeyError: |
323 log.warning(_( | 339 log.warning( |
324 'No handler for namespace "{namespace}", invitation ignored') | 340 _( |
325 .format(namespace=namespace)) | 341 'No handler for namespace "{namespace}", invitation ignored' |
342 ).format(namespace=namespace) | |
343 ) | |
326 else: | 344 else: |
327 await utils.as_deferred(cb, client, namespace, name, extra, *args) | 345 await utils.as_deferred(cb, client, namespace, name, extra, *args) |
328 | 346 |
329 | 347 |
330 @implementer(iwokkel.IDisco) | 348 @implementer(iwokkel.IDisco) |