Mercurial > libervia-backend
annotate libervia/backend/plugins/plugin_comp_ap_gateway/events.py @ 4283:23842a63ea00
plugin XEP-0060: add a `force` options for publish options in `send_items`:
The new `force` option can be used to force the update of configuration is
`publish-option` fails.
Use this new `force` option in XEP-0384.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 14 Jul 2024 16:45:17 +0200 |
parents | 0d7bb4df2343 |
children |
rev | line source |
---|---|
3904 | 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 Tuple | |
20 | |
21 import mimetypes | |
22 import html | |
23 | |
24 import shortuuid | |
25 from twisted.words.xish import domish | |
26 from twisted.words.protocols.jabber import jid | |
27 | |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
28 from libervia.backend.core.i18n import _ |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
29 from libervia.backend.core.log import getLogger |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
30 from libervia.backend.core import exceptions |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
31 from libervia.backend.tools.common import date_utils, uri |
3904 | 32 |
33 from .constants import NS_AP_PUBLIC, TYPE_ACTOR, TYPE_EVENT, TYPE_ITEM | |
34 | |
35 | |
36 log = getLogger(__name__) | |
37 | |
38 # direct copy of what Mobilizon uses | |
39 AP_EVENTS_CONTEXT = { | |
40 "@language": "und", | |
41 "Hashtag": "as:Hashtag", | |
42 "PostalAddress": "sc:PostalAddress", | |
43 "PropertyValue": "sc:PropertyValue", | |
44 "address": {"@id": "sc:address", "@type": "sc:PostalAddress"}, | |
45 "addressCountry": "sc:addressCountry", | |
46 "addressLocality": "sc:addressLocality", | |
47 "addressRegion": "sc:addressRegion", | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
48 "anonymousParticipationEnabled": { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
49 "@id": "mz:anonymousParticipationEnabled", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
50 "@type": "sc:Boolean", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
51 }, |
3904 | 52 "category": "sc:category", |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
53 "commentsEnabled": {"@id": "pt:commentsEnabled", "@type": "sc:Boolean"}, |
3904 | 54 "discoverable": "toot:discoverable", |
55 "discussions": {"@id": "mz:discussions", "@type": "@id"}, | |
56 "events": {"@id": "mz:events", "@type": "@id"}, | |
57 "ical": "http://www.w3.org/2002/12/cal/ical#", | |
58 "inLanguage": "sc:inLanguage", | |
59 "isOnline": {"@id": "mz:isOnline", "@type": "sc:Boolean"}, | |
60 "joinMode": {"@id": "mz:joinMode", "@type": "mz:joinModeType"}, | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
61 "joinModeType": {"@id": "mz:joinModeType", "@type": "rdfs:Class"}, |
3904 | 62 "location": {"@id": "sc:location", "@type": "sc:Place"}, |
63 "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", | |
64 "maximumAttendeeCapacity": "sc:maximumAttendeeCapacity", | |
65 "memberCount": {"@id": "mz:memberCount", "@type": "sc:Integer"}, | |
66 "members": {"@id": "mz:members", "@type": "@id"}, | |
67 "mz": "https://joinmobilizon.org/ns#", | |
68 "openness": {"@id": "mz:openness", "@type": "@id"}, | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
69 "participantCount": {"@id": "mz:participantCount", "@type": "sc:Integer"}, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
70 "participationMessage": {"@id": "mz:participationMessage", "@type": "sc:Text"}, |
3904 | 71 "postalCode": "sc:postalCode", |
72 "posts": {"@id": "mz:posts", "@type": "@id"}, | |
73 "propertyID": "sc:propertyID", | |
74 "pt": "https://joinpeertube.org/ns#", | |
75 "remainingAttendeeCapacity": "sc:remainingAttendeeCapacity", | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
76 "repliesModerationOption": { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
77 "@id": "mz:repliesModerationOption", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
78 "@type": "mz:repliesModerationOptionType", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
79 }, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
80 "repliesModerationOptionType": { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
81 "@id": "mz:repliesModerationOptionType", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
82 "@type": "rdfs:Class", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
83 }, |
3904 | 84 "resources": {"@id": "mz:resources", "@type": "@id"}, |
85 "sc": "http://schema.org#", | |
86 "streetAddress": "sc:streetAddress", | |
87 "timezone": {"@id": "mz:timezone", "@type": "sc:Text"}, | |
88 "todos": {"@id": "mz:todos", "@type": "@id"}, | |
89 "toot": "http://joinmastodon.org/ns#", | |
90 "uuid": "sc:identifier", | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
91 "value": "sc:value", |
3904 | 92 } |
93 | |
94 | |
95 class APEvents: | |
96 """XMPP Events <=> AP Events conversion""" | |
97 | |
98 def __init__(self, apg): | |
99 self.host = apg.host | |
100 self.apg = apg | |
4027
26c3e1bc7fb7
plugin XEP-0471: renamed "events" plugin to XEP-0471 now that there is a XEP
Goffi <goffi@goffi.org>
parents:
4023
diff
changeset
|
101 self._events = self.host.plugins["XEP-0471"] |
3904 | 102 |
103 async def event_data_2_ap_item( | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
104 self, event_data: dict, author_jid: jid.JID, is_new: bool = True |
3904 | 105 ) -> dict: |
106 """Convert event data to AP activity | |
107 | |
108 @param event_data: event data as used in [plugin_exp_events] | |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
109 @param author_jid: jid of the publisher of the event |
3904 | 110 @param is_new: if True, the item is a new one (no instance has been found in |
111 cache). | |
112 If True, a "Create" activity will be generated, otherwise an "Update" one will | |
113 be | |
114 @return: AP activity wrapping an Event object | |
115 """ | |
116 if not event_data.get("id"): | |
117 event_data["id"] = shortuuid.uuid() | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
4027
diff
changeset
|
118 ap_account = await self.apg.get_ap_account_from_jid_and_node( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
119 author_jid, self._events.namespace |
3904 | 120 ) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
4027
diff
changeset
|
121 url_actor = self.apg.build_apurl(TYPE_ACTOR, ap_account) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
4027
diff
changeset
|
122 url_item = self.apg.build_apurl(TYPE_ITEM, ap_account, event_data["id"]) |
3904 | 123 ap_object = { |
124 "actor": url_actor, | |
125 "attributedTo": url_actor, | |
126 "to": [NS_AP_PUBLIC], | |
127 "id": url_item, | |
128 "type": TYPE_EVENT, | |
129 "name": next(iter(event_data["name"].values())), | |
130 "startTime": date_utils.date_fmt(event_data["start"], "iso"), | |
131 "endTime": date_utils.date_fmt(event_data["end"], "iso"), | |
132 "url": url_item, | |
133 } | |
134 | |
135 attachment = ap_object["attachment"] = [] | |
136 | |
137 # FIXME: we only handle URL head-picture for now | |
138 # TODO: handle jingle and use file metadata | |
139 try: | |
140 head_picture_url = event_data["head-picture"]["sources"][0]["url"] | |
141 except (KeyError, IndexError, TypeError): | |
142 pass | |
143 else: | |
144 media_type = mimetypes.guess_type(head_picture_url, False)[0] or "image/jpeg" | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
145 attachment.append( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
146 { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
147 "name": "Banner", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
148 "type": "Document", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
149 "mediaType": media_type, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
150 "url": head_picture_url, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
151 } |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
152 ) |
3904 | 153 |
154 descriptions = event_data.get("descriptions") | |
155 if descriptions: | |
156 for description in descriptions: | |
157 content = description["description"] | |
158 if description["type"] == "xhtml": | |
159 break | |
160 else: | |
161 content = f"<p>{html.escape(content)}</p>" # type: ignore | |
162 ap_object["content"] = content | |
163 | |
164 categories = event_data.get("categories") | |
165 if categories: | |
166 tag = ap_object["tag"] = [] | |
167 for category in categories: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
168 tag.append( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
169 { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
170 "name": f"#{category['term']}", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
171 "type": "Hashtag", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
172 } |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
173 ) |
3904 | 174 |
175 locations = event_data.get("locations") | |
176 if locations: | |
177 ap_loc = ap_object["location"] = {} | |
178 # we only use the first found location | |
179 location = locations[0] | |
180 for source, dest in ( | |
181 ("description", "name"), | |
182 ("lat", "latitude"), | |
183 ("lon", "longitude"), | |
184 ): | |
185 value = location.get(source) | |
186 if value is not None: | |
187 ap_loc[dest] = value | |
188 for source, dest in ( | |
189 ("country", "addressCountry"), | |
190 ("locality", "addressLocality"), | |
191 ("region", "addressRegion"), | |
192 ("postalcode", "postalCode"), | |
193 ("street", "streetAddress"), | |
194 ): | |
195 value = location.get(source) | |
196 if value is not None: | |
197 ap_loc.setdefault("address", {})[dest] = value | |
198 | |
199 if event_data.get("comments"): | |
200 ap_object["commentsEnabled"] = True | |
201 | |
202 extra = event_data.get("extra") | |
203 | |
204 if extra: | |
205 status = extra.get("status") | |
206 if status: | |
207 ap_object["ical:status"] = status.upper() | |
208 | |
209 website = extra.get("website") | |
210 if website: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
211 attachment.append( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
212 { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
213 "href": website, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
214 "mediaType": "text/html", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
215 "name": "Website", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
216 "type": "Link", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
217 } |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
218 ) |
3904 | 219 |
220 accessibility = extra.get("accessibility") | |
221 if accessibility: | |
222 wheelchair = accessibility.get("wheelchair") | |
223 if wheelchair: | |
224 if wheelchair == "full": | |
225 ap_wc_value = "fully" | |
226 elif wheelchair == "partial": | |
227 ap_wc_value = "partially" | |
228 elif wheelchair == "no": | |
229 ap_wc_value = "no" | |
230 else: | |
231 log.error(f"unexpected wheelchair value: {wheelchair}") | |
232 ap_wc_value = None | |
233 if ap_wc_value is not None: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
234 attachment.append( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
235 { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
236 "propertyID": "mz:accessibility:wheelchairAccessible", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
237 "type": "PropertyValue", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
238 "value": ap_wc_value, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
239 } |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
240 ) |
3904 | 241 |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3904
diff
changeset
|
242 activity = self.apg.create_activity( |
3904 | 243 "Create" if is_new else "Update", url_actor, ap_object, activity_id=url_item |
244 ) | |
245 activity["@context"].append(AP_EVENTS_CONTEXT) | |
246 return activity | |
247 | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
248 async def ap_item_2_event_data(self, requestor_actor_id: str, ap_item: dict) -> dict: |
3904 | 249 """Convert AP activity or object to event data |
250 | |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
251 @param requestor_actor_id: ID of the actor doing the request. |
3904 | 252 @param ap_item: ActivityPub item to convert |
253 Can be either an activity of an object | |
254 @return: AP Item's Object and event data | |
255 @raise exceptions.DataError: something is invalid in the AP item | |
256 """ | |
257 is_activity = self.apg.is_activity(ap_item) | |
258 if is_activity: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
259 ap_object = await self.apg.ap_get_object( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
260 requestor_actor_id, ap_item, "object" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
261 ) |
3904 | 262 if not ap_object: |
263 log.warning(f'No "object" found in AP item {ap_item!r}') | |
264 raise exceptions.DataError | |
265 else: | |
266 ap_object = ap_item | |
267 | |
268 # id | |
269 if "_repeated" in ap_item: | |
270 # if the event is repeated, we use the original one ID | |
271 repeated_uri = ap_item["_repeated"]["uri"] | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
4027
diff
changeset
|
272 parsed_uri = uri.parse_xmpp_uri(repeated_uri) |
3904 | 273 object_id = parsed_uri["item"] |
274 else: | |
275 object_id = ap_object.get("id") | |
276 if not object_id: | |
277 raise exceptions.DataError('"id" is missing in AP object') | |
278 | |
279 if ap_item["type"] != TYPE_EVENT: | |
280 raise exceptions.DataError("AP Object is not an event") | |
281 | |
282 # author | |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
283 actor = await self.apg.ap_get_sender_actor(requestor_actor_id, ap_object) |
3904 | 284 |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
285 account = await self.apg.get_ap_account_from_id(requestor_actor_id, actor) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
4027
diff
changeset
|
286 author_jid = self.apg.get_local_jid_from_account(account).full() |
3904 | 287 |
288 # name, start, end | |
289 event_data = { | |
290 "id": object_id, | |
291 "name": {"": ap_object.get("name") or "unnamed"}, | |
292 "start": date_utils.date_parse(ap_object["startTime"]), | |
293 "end": date_utils.date_parse(ap_object["endTime"]), | |
294 } | |
295 | |
296 # attachments/extra | |
297 event_data["extra"] = extra = {} | |
298 attachments = ap_object.get("attachment") or [] | |
299 for attachment in attachments: | |
300 name = attachment.get("name") | |
301 if name == "Banner": | |
302 try: | |
303 url = attachment["url"] | |
304 except KeyError: | |
305 log.warning(f"invalid attachment: {attachment}") | |
306 continue | |
307 event_data["head-picture"] = {"sources": [{"url": url}]} | |
308 elif name == "Website": | |
309 try: | |
310 url = attachment["href"] | |
311 except KeyError: | |
312 log.warning(f"invalid attachment: {attachment}") | |
313 continue | |
314 extra["website"] = url | |
315 else: | |
316 log.debug(f"unmanaged attachment: {attachment}") | |
317 | |
318 # description | |
319 content = ap_object.get("content") | |
320 if content: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
321 event_data["descriptions"] = [{"type": "xhtml", "description": content}] |
3904 | 322 |
323 # categories | |
324 tags = ap_object.get("tag") | |
325 if tags: | |
326 categories = event_data["categories"] = [] | |
327 for tag in tags: | |
328 if tag.get("type") == "Hashtag": | |
329 try: | |
330 term = tag["name"][1:] | |
331 except KeyError: | |
332 log.warning(f"invalid tag: {tag}") | |
333 continue | |
334 categories.append({"term": term}) | |
335 | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
336 # location |
3904 | 337 ap_location = ap_object.get("location") |
338 if ap_location: | |
339 location = {} | |
340 for source, dest in ( | |
341 ("name", "description"), | |
342 ("latitude", "lat"), | |
343 ("longitude", "lon"), | |
344 ): | |
345 value = ap_location.get(source) | |
346 if value is not None: | |
347 location[dest] = value | |
348 address = ap_location.get("address") | |
349 if address: | |
350 for source, dest in ( | |
351 ("addressCountry", "country"), | |
352 ("addressLocality", "locality"), | |
353 ("addressRegion", "region"), | |
354 ("postalCode", "postalcode"), | |
355 ("streetAddress", "street"), | |
356 ): | |
357 value = address.get(source) | |
358 if value is not None: | |
359 location[dest] = value | |
360 if location: | |
361 event_data["locations"] = [location] | |
362 | |
363 # rsvp | |
364 # So far Mobilizon seems to only handle participate/don't participate, thus we use | |
365 # a simple "yes"/"no" form. | |
366 rsvp_data = {"fields": []} | |
367 event_data["rsvp"] = [rsvp_data] | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
368 rsvp_data["fields"].append( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
369 { |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
370 "type": "list-single", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
371 "name": "attending", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
372 "label": "Attending", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
373 "options": [ |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
374 {"label": "yes", "value": "yes"}, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
375 {"label": "no", "value": "no"}, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
376 ], |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
377 "required": True, |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
378 } |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
379 ) |
3904 | 380 |
381 # comments | |
382 | |
383 if ap_object.get("commentsEnabled"): | |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
384 __, comments_node = await self.apg.get_comments_nodes( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
385 requestor_actor_id, object_id, None |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
386 ) |
3904 | 387 event_data["comments"] = { |
388 "service": author_jid, | |
389 "node": comments_node, | |
390 } | |
391 | |
392 # extra | |
393 # part of extra come from "attachment" above | |
394 | |
395 status = ap_object.get("ical:status") | |
396 if status is None: | |
397 pass | |
398 elif status in ("CONFIRMED", "CANCELLED", "TENTATIVE"): | |
399 extra["status"] = status.lower() | |
400 else: | |
401 log.warning(f"unknown event status: {status}") | |
402 | |
403 return event_data | |
404 | |
405 async def ap_item_2_event_data_and_elt( | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
406 self, requestor_actor_id: str, ap_item: dict |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
407 ) -> tuple[dict, domish.Element]: |
3904 | 408 """Convert AP item to parsed event data and corresponding item element""" |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
409 event_data = await self.ap_item_2_event_data(requestor_actor_id, ap_item) |
3904 | 410 event_elt = self._events.event_data_2_event_elt(event_data) |
411 item_elt = domish.Element((None, "item")) | |
412 item_elt["id"] = event_data["id"] | |
413 item_elt.addChild(event_elt) | |
414 return event_data, item_elt | |
415 | |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
416 async def ap_item_2_event_elt( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
417 self, requestor_actor_id: str, ap_item: dict |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
418 ) -> domish.Element: |
3904 | 419 """Convert AP item to XMPP item element""" |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
420 __, item_elt = await self.ap_item_2_event_data_and_elt( |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4259
diff
changeset
|
421 requestor_actor_id, ap_item |
4259
49019947cc76
component AP Gateway: implement HTTP GET signature.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
422 ) |
3904 | 423 return item_elt |