Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_xep_0498.py @ 4336:6e0918e638ee
plugin XEP-0498: "Pubsub File Sharing" implementation:
Partial implementation of XEP-0498, necessary to implement the service part in email
gateway.
rel 453
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 03 Dec 2024 00:13:23 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4335:430d5d99a740 | 4336:6e0918e638ee |
---|---|
1 #!/usr/bin/env python3 | |
2 | |
3 # Libervia plugin to jingle session publishing. | |
4 # Copyright (C) 2009-2024 Jérôme Poisson (goffi@goffi.org) | |
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 | |
19 from typing import TYPE_CHECKING, Final, Self | |
20 | |
21 from pydantic import BaseModel | |
22 from twisted.words.protocols.jabber import jid | |
23 from twisted.words.protocols.jabber.xmlstream import XMPPHandler | |
24 from twisted.words.xish import domish | |
25 from wokkel import disco, iwokkel, pubsub | |
26 from zope.interface import implementer | |
27 | |
28 from libervia.backend.core.constants import Const as C | |
29 from libervia.backend.core.core_types import SatXMPPEntity | |
30 from libervia.backend.core.i18n import _ | |
31 from libervia.backend.core.log import getLogger | |
32 from libervia.backend.plugins.plugin_xep_0234 import NS_JINGLE_FT | |
33 from libervia.backend.plugins.plugin_xep_0358 import JinglePub | |
34 from libervia.backend.plugins.plugin_xep_0446 import FileMetadata | |
35 from libervia.backend.plugins.plugin_xep_0447 import FileSharing, JinglePubSource | |
36 | |
37 if TYPE_CHECKING: | |
38 from libervia.backend.core.main import LiberviaBackend | |
39 | |
40 log = getLogger(__name__) | |
41 | |
42 | |
43 PLUGIN_INFO = { | |
44 C.PI_NAME: "Pubsub File Sharing", | |
45 C.PI_IMPORT_NAME: "XEP-0498", | |
46 C.PI_TYPE: "XEP", | |
47 C.PI_MODES: C.PLUG_MODE_BOTH, | |
48 C.PI_PROTOCOLS: [], | |
49 C.PI_DEPENDENCIES: [ | |
50 "XEP-0060", | |
51 "XEP-0447", | |
52 ], | |
53 C.PI_RECOMMENDATIONS: [], | |
54 C.PI_MAIN: "XEP_0498", | |
55 C.PI_HANDLER: "yes", | |
56 C.PI_DESCRIPTION: _("""Share and retrieve files via Pubsub."""), | |
57 } | |
58 | |
59 NS_PUBSUB_FILE_SHARING: Final = "urn:xmpp:pubsub-file-sharing:0" | |
60 | |
61 | |
62 class NodeData(BaseModel): | |
63 """Model for JinglePub element.""" | |
64 | |
65 files: dict[str, FileSharing] | |
66 | |
67 def to_elements(self) -> list[domish.Element]: | |
68 """Return the list of item elements corresponding to this model""" | |
69 items = [] | |
70 for item_id, file_sharing in self.files.items(): | |
71 item_elt = pubsub.Item(id=item_id, payload=file_sharing.to_element()) | |
72 items.append(item_elt) | |
73 | |
74 return items | |
75 | |
76 @classmethod | |
77 def from_files_data(cls, source_jid: jid.JID, files_data: list[dict]) -> Self: | |
78 """Generate from list of file data as returned by ``memory.get_files``. | |
79 | |
80 @param files_data: list of files data as returned by ``memory.get_files``. | |
81 @return: Instance of ``NodeData``. | |
82 """ | |
83 kw = {} | |
84 for file_data in files_data: | |
85 file_metadata = FileMetadata.from_filedata_dict(file_data) | |
86 source = JinglePubSource( | |
87 from_jid=source_jid, | |
88 id=file_data["id"], | |
89 descriptions=[domish.Element((NS_JINGLE_FT, "description"))], | |
90 ) | |
91 # We don't know if names are unique, so we add ID to be sure. | |
92 key = f'{file_data["name"]}_{file_data["id"]}' | |
93 kw[key] = FileSharing(file=file_metadata, sources=[source]) | |
94 | |
95 return cls(files=kw) | |
96 | |
97 | |
98 class XEP_0498: | |
99 namespace = NS_PUBSUB_FILE_SHARING | |
100 | |
101 def __init__(self, host: "LiberviaBackend") -> None: | |
102 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization") | |
103 self.host = host | |
104 host.register_namespace("pubsub-file-sharing", NS_PUBSUB_FILE_SHARING) | |
105 | |
106 def get_handler(self, client: SatXMPPEntity) -> XMPPHandler: | |
107 return PubsubFileSharingHandler(self) | |
108 | |
109 | |
110 @implementer(iwokkel.IDisco) | |
111 class PubsubFileSharingHandler(XMPPHandler): | |
112 | |
113 def __init__(self, plugin_parent): | |
114 self.plugin_parent = plugin_parent | |
115 | |
116 def getDiscoInfo( | |
117 self, requestor: jid.JID, target: jid.JID, nodeIdentifier: str = "" | |
118 ) -> list[disco.DiscoFeature]: | |
119 return [ | |
120 disco.DiscoFeature(NS_PUBSUB_FILE_SHARING), | |
121 ] | |
122 | |
123 def getDiscoItems( | |
124 self, requestor: jid.JID, target: jid.JID, nodeIdentifier: str = "" | |
125 ) -> list[disco.DiscoItems]: | |
126 return [] |