comparison sat/plugins/plugin_comp_ap_gateway/pubsub_service.py @ 3729:86eea17cafa7

component AP gateway: split plugin in several files: constants, HTTP server and Pubsub service have been put in separated files. rel: 363
author Goffi <goffi@goffi.org>
date Mon, 31 Jan 2022 18:35:49 +0100
parents sat/plugins/plugin_comp_ap_gateway.py@b15644cae50d
children a8c7e5cef0cb
comparison
equal deleted inserted replaced
3728:b15644cae50d 3729:86eea17cafa7
1 #!/usr/bin/env python3
2
3 # Libervia ActivityPub Gateway
4 # Copyright (C) 2009-2021 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 Optional, List
20
21 from twisted.words.protocols.jabber import jid, error
22 from twisted.words.xish import domish
23 from wokkel import rsm
24
25 from sat.core.i18n import _
26 from sat.core.log import getLogger
27 from sat.tools.utils import ensure_deferred
28
29
30 log = getLogger(__name__)
31
32
33 class APPubsubService(rsm.PubSubService):
34 """Pubsub service for XMPP requests"""
35
36 def __init__(self, apg):
37 super(APPubsubService, self).__init__()
38 self.host = apg.host
39 self.apg = apg
40 self.discoIdentity = {
41 "category": "pubsub",
42 "type": "service",
43 "name": "Libervia ActivityPub Gateway",
44 }
45
46 @ensure_deferred
47 async def publish(self, requestor, service, nodeIdentifier, items):
48 raise NotImplementedError
49
50 @ensure_deferred
51 async def items(
52 self,
53 requestor: jid.JID,
54 service: jid.JID,
55 node: str,
56 maxItems: Optional[int],
57 itemIdentifiers: Optional[List[str]],
58 rsm_req: Optional[rsm.RSMRequest]
59 ) -> List[domish.Element]:
60 if not service.user:
61 return []
62 ap_account = self.host.plugins["XEP-0106"].unescape(service.user)
63 if ap_account.count("@") != 1:
64 log.warning(f"Invalid AP account used by {requestor}: {ap_account!r}")
65 return []
66 if node != self.apg._m.namespace:
67 raise error.StanzaError(
68 "feature-not-implemented",
69 text=f"{VERSION} only supports {self.apg._m.namespace} "
70 "node for now"
71 )
72 if rsm_req is None:
73 if maxItems is None:
74 maxItems = 20
75 kwargs = {
76 "max_items": maxItems,
77 "chronological_pagination": False,
78 }
79 else:
80 if len(
81 [v for v in (rsm_req.after, rsm_req.before, rsm_req.index)
82 if v is not None]
83 ) > 1:
84 raise error.StanzaError(
85 "bad-request",
86 text="You can't use after, before and index at the same time"
87 )
88 kwargs = {"max_items": rsm_req.max}
89 if rsm_req.after is not None:
90 kwargs["after_id"] = rsm_req.after
91 elif rsm_req.before is not None:
92 kwargs["chronological_pagination"] = False
93 if rsm_req.before != "":
94 kwargs["after_id"] = rsm_req.before
95 elif rsm_req.index is not None:
96 kwargs["start_index"] = rsm_req.index
97
98 log.info(
99 f"No cache found for node {node} at {service} (AP account {ap_account}), "
100 "using Collection Paging to RSM translation"
101 )
102 return await self.apg.getAPItems(ap_account, **kwargs)
103
104 @ensure_deferred
105 async def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
106 raise NotImplementedError
107
108 def getNodeInfo(
109 self,
110 requestor: jid.JID,
111 service: jid.JID,
112 nodeIdentifier: str,
113 pep: bool = False,
114 recipient: Optional[jid.JID] = None
115 ) -> Optional[dict]:
116 if not nodeIdentifier:
117 return None
118 info = {
119 "type": "leaf",
120 "meta-data": [
121 {"var": "pubsub#persist_items", "type": "boolean", "value": True},
122 {"var": "pubsub#max_items", "value": "max"},
123 {"var": "pubsub#access_model", "type": "list-single", "value": "open"},
124 {"var": "pubsub#publish_model", "type": "list-single", "value": "open"},
125
126 ]
127
128 }
129 return info