slidge 0.2.0a9__py3-none-any.whl → 0.2.0b0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- slidge/__main__.py +2 -3
- slidge/__version__.py +1 -1
- slidge/command/adhoc.py +1 -1
- slidge/command/base.py +4 -4
- slidge/command/user.py +5 -1
- slidge/contact/roster.py +9 -0
- slidge/core/config.py +0 -3
- slidge/core/dispatcher/__init__.py +3 -0
- slidge/core/{gateway → dispatcher}/caps.py +6 -4
- slidge/core/{gateway → dispatcher}/disco.py +11 -17
- slidge/core/dispatcher/message/__init__.py +10 -0
- slidge/core/dispatcher/message/chat_state.py +40 -0
- slidge/core/dispatcher/message/marker.py +62 -0
- slidge/core/dispatcher/message/message.py +397 -0
- slidge/core/dispatcher/muc/__init__.py +12 -0
- slidge/core/dispatcher/muc/admin.py +98 -0
- slidge/core/{gateway → dispatcher/muc}/mam.py +26 -15
- slidge/core/dispatcher/muc/misc.py +121 -0
- slidge/core/dispatcher/muc/owner.py +96 -0
- slidge/core/{gateway → dispatcher/muc}/ping.py +10 -15
- slidge/core/dispatcher/presence.py +177 -0
- slidge/core/{gateway → dispatcher}/registration.py +23 -2
- slidge/core/{gateway → dispatcher}/search.py +9 -14
- slidge/core/dispatcher/session_dispatcher.py +84 -0
- slidge/core/dispatcher/util.py +174 -0
- slidge/core/{gateway/vcard_temp.py → dispatcher/vcard.py} +26 -12
- slidge/core/{gateway/base.py → gateway.py} +42 -137
- slidge/core/mixins/attachment.py +24 -8
- slidge/core/mixins/base.py +2 -2
- slidge/core/mixins/lock.py +10 -8
- slidge/core/mixins/message.py +9 -203
- slidge/core/mixins/message_text.py +211 -0
- slidge/core/pubsub.py +2 -1
- slidge/core/session.py +28 -2
- slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +83 -0
- slidge/db/alembic/versions/45c24cc73c91_add_bob.py +42 -0
- slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +12 -1
- slidge/db/models.py +16 -1
- slidge/db/store.py +144 -11
- slidge/group/bookmarks.py +23 -1
- slidge/group/participant.py +5 -5
- slidge/group/room.py +10 -1
- slidge/{core/gateway → slixfix}/delivery_receipt.py +1 -1
- slidge/util/test.py +9 -5
- slidge/util/types.py +6 -0
- slidge/util/util.py +5 -2
- {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/METADATA +2 -1
- {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/RECORD +51 -40
- slidge-0.2.0b0.dist-info/entry_points.txt +3 -0
- slidge/core/gateway/__init__.py +0 -3
- slidge/core/gateway/muc_admin.py +0 -35
- slidge/core/gateway/presence.py +0 -95
- slidge/core/gateway/session_dispatcher.py +0 -895
- slidge-0.2.0a9.dist-info/entry_points.txt +0 -3
- {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/LICENSE +0 -0
- {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/WHEEL +0 -0
slidge/core/mixins/message.py
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
import logging
|
2
2
|
import uuid
|
3
3
|
import warnings
|
4
|
-
from
|
5
|
-
from typing import TYPE_CHECKING, Iterable, Optional
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
6
5
|
|
7
6
|
from slixmpp import Iq, Message
|
8
7
|
|
9
8
|
from ...slixfix.xep_0490.mds import PUBLISH_OPTIONS
|
10
|
-
from ...util.types import
|
11
|
-
ChatState,
|
12
|
-
LegacyMessageType,
|
13
|
-
LegacyThreadType,
|
14
|
-
LinkPreview,
|
15
|
-
Marker,
|
16
|
-
MessageReference,
|
17
|
-
ProcessingHint,
|
18
|
-
)
|
9
|
+
from ...util.types import ChatState, LegacyMessageType, Marker
|
19
10
|
from .attachment import AttachmentMixin
|
20
11
|
from .message_maker import MessageMaker
|
12
|
+
from .message_text import TextMessageMixin
|
21
13
|
|
22
14
|
if TYPE_CHECKING:
|
23
15
|
from ...group import LegacyMUC
|
@@ -158,205 +150,19 @@ class MarkerMixin(MessageMaker):
|
|
158
150
|
self.session.log.debug("Could not MDS mark", exc_info=e)
|
159
151
|
|
160
152
|
|
161
|
-
class ContentMessageMixin(AttachmentMixin):
|
162
|
-
|
163
|
-
if hints is not None:
|
164
|
-
return hints
|
165
|
-
elif self.mtype == "chat":
|
166
|
-
return {"markable", "store"}
|
167
|
-
elif self.mtype == "groupchat":
|
168
|
-
return {"markable"}
|
169
|
-
|
170
|
-
def __replace_id(self, legacy_msg_id: LegacyMessageType):
|
171
|
-
if self.mtype == "groupchat":
|
172
|
-
return self.xmpp.store.sent.get_group_xmpp_id(
|
173
|
-
self.session.user_pk, str(legacy_msg_id)
|
174
|
-
) or self._legacy_to_xmpp(legacy_msg_id)
|
175
|
-
else:
|
176
|
-
return self._legacy_to_xmpp(legacy_msg_id)
|
177
|
-
|
178
|
-
def send_text(
|
179
|
-
self,
|
180
|
-
body: str,
|
181
|
-
legacy_msg_id: Optional[LegacyMessageType] = None,
|
182
|
-
*,
|
183
|
-
when: Optional[datetime] = None,
|
184
|
-
reply_to: Optional[MessageReference] = None,
|
185
|
-
thread: Optional[LegacyThreadType] = None,
|
186
|
-
hints: Optional[Iterable[ProcessingHint]] = None,
|
187
|
-
carbon=False,
|
188
|
-
archive_only=False,
|
189
|
-
correction=False,
|
190
|
-
correction_event_id: Optional[LegacyMessageType] = None,
|
191
|
-
link_previews: Optional[list[LinkPreview]] = None,
|
192
|
-
**send_kwargs,
|
193
|
-
):
|
194
|
-
"""
|
195
|
-
Send a text message from this :term:`XMPP Entity`.
|
196
|
-
|
197
|
-
:param body: Content of the message
|
198
|
-
:param legacy_msg_id: If you want to be able to transport read markers from the gateway
|
199
|
-
user to the legacy network, specify this
|
200
|
-
:param when: when the message was sent, for a "delay" tag (:xep:`0203`)
|
201
|
-
:param reply_to: Quote another message (:xep:`0461`)
|
202
|
-
:param hints:
|
203
|
-
:param thread:
|
204
|
-
:param carbon: (only used if called on a :class:`LegacyContact`)
|
205
|
-
Set this to ``True`` if this is actually a message sent **to** the
|
206
|
-
:class:`LegacyContact` by the :term:`User`.
|
207
|
-
Use this to synchronize outgoing history for legacy official apps.
|
208
|
-
:param correction: whether this message is a correction or not
|
209
|
-
:param correction_event_id: in the case where an ID is associated with the legacy
|
210
|
-
'correction event', specify it here to use it on the XMPP side. If not specified,
|
211
|
-
a random ID will be used.
|
212
|
-
:param link_previews: A little of sender (or server, or gateway)-generated
|
213
|
-
previews of URLs linked in the body.
|
214
|
-
:param archive_only: (only in groups) Do not send this message to user,
|
215
|
-
but store it in the archive. Meant to be used during ``MUC.backfill()``
|
216
|
-
"""
|
217
|
-
if carbon:
|
218
|
-
if not correction and self.xmpp.store.sent.was_sent_by_user(
|
219
|
-
self.session.user_pk, str(legacy_msg_id)
|
220
|
-
):
|
221
|
-
log.warning(
|
222
|
-
"Carbon message for a message an XMPP has sent? This is a bug! %s",
|
223
|
-
legacy_msg_id,
|
224
|
-
)
|
225
|
-
return
|
226
|
-
self.xmpp.store.sent.set_message(
|
227
|
-
self.session.user_pk,
|
228
|
-
str(legacy_msg_id),
|
229
|
-
self.session.legacy_to_xmpp_msg_id(legacy_msg_id),
|
230
|
-
)
|
231
|
-
hints = self.__default_hints(hints)
|
232
|
-
msg = self._make_message(
|
233
|
-
mbody=body,
|
234
|
-
legacy_msg_id=correction_event_id if correction else legacy_msg_id,
|
235
|
-
when=when,
|
236
|
-
reply_to=reply_to,
|
237
|
-
hints=hints or (),
|
238
|
-
carbon=carbon,
|
239
|
-
thread=thread,
|
240
|
-
link_previews=link_previews,
|
241
|
-
)
|
242
|
-
if correction:
|
243
|
-
msg["replace"]["id"] = self.__replace_id(legacy_msg_id)
|
244
|
-
return self._send(
|
245
|
-
msg,
|
246
|
-
archive_only=archive_only,
|
247
|
-
carbon=carbon,
|
248
|
-
legacy_msg_id=legacy_msg_id,
|
249
|
-
**send_kwargs,
|
250
|
-
)
|
251
|
-
|
252
|
-
def correct(
|
253
|
-
self,
|
254
|
-
legacy_msg_id: LegacyMessageType,
|
255
|
-
new_text: str,
|
256
|
-
*,
|
257
|
-
when: Optional[datetime] = None,
|
258
|
-
reply_to: Optional[MessageReference] = None,
|
259
|
-
thread: Optional[LegacyThreadType] = None,
|
260
|
-
hints: Optional[Iterable[ProcessingHint]] = None,
|
261
|
-
carbon=False,
|
262
|
-
archive_only=False,
|
263
|
-
correction_event_id: Optional[LegacyMessageType] = None,
|
264
|
-
link_previews: Optional[list[LinkPreview]] = None,
|
265
|
-
**send_kwargs,
|
266
|
-
):
|
267
|
-
"""
|
268
|
-
Modify a message that was previously sent by this :term:`XMPP Entity`.
|
269
|
-
|
270
|
-
Uses last message correction (:xep:`0308`)
|
271
|
-
|
272
|
-
:param new_text: New content of the message
|
273
|
-
:param legacy_msg_id: The legacy message ID of the message to correct
|
274
|
-
:param when: when the message was sent, for a "delay" tag (:xep:`0203`)
|
275
|
-
:param reply_to: Quote another message (:xep:`0461`)
|
276
|
-
:param hints:
|
277
|
-
:param thread:
|
278
|
-
:param carbon: (only in 1:1) Reflect a message sent to this ``Contact`` by the user.
|
279
|
-
Use this to synchronize outgoing history for legacy official apps.
|
280
|
-
:param archive_only: (only in groups) Do not send this message to user,
|
281
|
-
but store it in the archive. Meant to be used during ``MUC.backfill()``
|
282
|
-
:param correction_event_id: in the case where an ID is associated with the legacy
|
283
|
-
'correction event', specify it here to use it on the XMPP side. If not specified,
|
284
|
-
a random ID will be used.
|
285
|
-
:param link_previews: A little of sender (or server, or gateway)-generated
|
286
|
-
previews of URLs linked in the body.
|
287
|
-
"""
|
288
|
-
self.send_text(
|
289
|
-
new_text,
|
290
|
-
legacy_msg_id,
|
291
|
-
when=when,
|
292
|
-
reply_to=reply_to,
|
293
|
-
hints=hints,
|
294
|
-
carbon=carbon,
|
295
|
-
thread=thread,
|
296
|
-
correction=True,
|
297
|
-
archive_only=archive_only,
|
298
|
-
correction_event_id=correction_event_id,
|
299
|
-
link_previews=link_previews,
|
300
|
-
**send_kwargs,
|
301
|
-
)
|
302
|
-
|
303
|
-
def react(
|
304
|
-
self,
|
305
|
-
legacy_msg_id: LegacyMessageType,
|
306
|
-
emojis: Iterable[str] = (),
|
307
|
-
thread: Optional[LegacyThreadType] = None,
|
308
|
-
**kwargs,
|
309
|
-
):
|
310
|
-
"""
|
311
|
-
Send a reaction (:xep:`0444`) from this :term:`XMPP Entity`.
|
312
|
-
|
313
|
-
:param legacy_msg_id: The message which the reaction refers to.
|
314
|
-
:param emojis: An iterable of emojis used as reactions
|
315
|
-
:param thread:
|
316
|
-
"""
|
317
|
-
msg = self._make_message(
|
318
|
-
hints={"store"}, carbon=kwargs.get("carbon"), thread=thread
|
319
|
-
)
|
320
|
-
xmpp_id = kwargs.pop("xmpp_id", None)
|
321
|
-
if not xmpp_id:
|
322
|
-
xmpp_id = self._legacy_to_xmpp(legacy_msg_id)
|
323
|
-
self.xmpp["xep_0444"].set_reactions(msg, to_id=xmpp_id, reactions=emojis)
|
324
|
-
self._send(msg, **kwargs)
|
325
|
-
|
326
|
-
def retract(
|
327
|
-
self,
|
328
|
-
legacy_msg_id: LegacyMessageType,
|
329
|
-
thread: Optional[LegacyThreadType] = None,
|
330
|
-
**kwargs,
|
331
|
-
):
|
332
|
-
"""
|
333
|
-
Send a message retraction (:XEP:`0424`) from this :term:`XMPP Entity`.
|
334
|
-
|
335
|
-
:param legacy_msg_id: Legacy ID of the message to delete
|
336
|
-
:param thread:
|
337
|
-
"""
|
338
|
-
msg = self._make_message(
|
339
|
-
state=None,
|
340
|
-
hints={"store"},
|
341
|
-
mbody=f"/me retracted the message {legacy_msg_id}",
|
342
|
-
carbon=kwargs.get("carbon"),
|
343
|
-
thread=thread,
|
344
|
-
)
|
345
|
-
msg.enable("fallback")
|
346
|
-
# namespace version mismatch between slidge and slixmpp, update me later
|
347
|
-
msg["fallback"]["for"] = self.xmpp["xep_0424"].namespace[:-1] + "1"
|
348
|
-
msg["retract"]["id"] = msg["replace"]["id"] = self.__replace_id(legacy_msg_id)
|
349
|
-
self._send(msg, **kwargs)
|
153
|
+
class ContentMessageMixin(AttachmentMixin, TextMessageMixin):
|
154
|
+
pass
|
350
155
|
|
351
156
|
|
352
157
|
class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
|
353
158
|
def _privileged_send(self, msg: Message):
|
354
159
|
i = msg.get_id()
|
355
|
-
if
|
356
|
-
|
160
|
+
if i:
|
161
|
+
self.session.ignore_messages.add(i)
|
162
|
+
else:
|
163
|
+
i = "slidge-carbon-" + str(uuid.uuid4())
|
357
164
|
msg.set_id(i)
|
358
165
|
msg.del_origin_id()
|
359
|
-
self.session.ignore_messages.add(i)
|
360
166
|
try:
|
361
167
|
self.xmpp["xep_0356"].send_privileged_message(msg)
|
362
168
|
except PermissionError:
|
@@ -0,0 +1,211 @@
|
|
1
|
+
import logging
|
2
|
+
from datetime import datetime
|
3
|
+
from typing import Iterable, Optional
|
4
|
+
|
5
|
+
from ...util.types import (
|
6
|
+
LegacyMessageType,
|
7
|
+
LegacyThreadType,
|
8
|
+
LinkPreview,
|
9
|
+
MessageReference,
|
10
|
+
ProcessingHint,
|
11
|
+
)
|
12
|
+
from .message_maker import MessageMaker
|
13
|
+
|
14
|
+
|
15
|
+
class TextMessageMixin(MessageMaker):
|
16
|
+
def __default_hints(self, hints: Optional[Iterable[ProcessingHint]] = None):
|
17
|
+
if hints is not None:
|
18
|
+
return hints
|
19
|
+
elif self.mtype == "chat":
|
20
|
+
return {"markable", "store"}
|
21
|
+
elif self.mtype == "groupchat":
|
22
|
+
return {"markable"}
|
23
|
+
|
24
|
+
def _replace_id(self, legacy_msg_id: LegacyMessageType):
|
25
|
+
if self.mtype == "groupchat":
|
26
|
+
return self.xmpp.store.sent.get_group_xmpp_id(
|
27
|
+
self.session.user_pk, str(legacy_msg_id)
|
28
|
+
) or self._legacy_to_xmpp(legacy_msg_id)
|
29
|
+
else:
|
30
|
+
return self._legacy_to_xmpp(legacy_msg_id)
|
31
|
+
|
32
|
+
def send_text(
|
33
|
+
self,
|
34
|
+
body: str,
|
35
|
+
legacy_msg_id: Optional[LegacyMessageType] = None,
|
36
|
+
*,
|
37
|
+
when: Optional[datetime] = None,
|
38
|
+
reply_to: Optional[MessageReference] = None,
|
39
|
+
thread: Optional[LegacyThreadType] = None,
|
40
|
+
hints: Optional[Iterable[ProcessingHint]] = None,
|
41
|
+
carbon=False,
|
42
|
+
archive_only=False,
|
43
|
+
correction=False,
|
44
|
+
correction_event_id: Optional[LegacyMessageType] = None,
|
45
|
+
link_previews: Optional[list[LinkPreview]] = None,
|
46
|
+
**send_kwargs,
|
47
|
+
):
|
48
|
+
"""
|
49
|
+
Send a text message from this :term:`XMPP Entity`.
|
50
|
+
|
51
|
+
:param body: Content of the message
|
52
|
+
:param legacy_msg_id: If you want to be able to transport read markers from the gateway
|
53
|
+
user to the legacy network, specify this
|
54
|
+
:param when: when the message was sent, for a "delay" tag (:xep:`0203`)
|
55
|
+
:param reply_to: Quote another message (:xep:`0461`)
|
56
|
+
:param hints:
|
57
|
+
:param thread:
|
58
|
+
:param carbon: (only used if called on a :class:`LegacyContact`)
|
59
|
+
Set this to ``True`` if this is actually a message sent **to** the
|
60
|
+
:class:`LegacyContact` by the :term:`User`.
|
61
|
+
Use this to synchronize outgoing history for legacy official apps.
|
62
|
+
:param correction: whether this message is a correction or not
|
63
|
+
:param correction_event_id: in the case where an ID is associated with the legacy
|
64
|
+
'correction event', specify it here to use it on the XMPP side. If not specified,
|
65
|
+
a random ID will be used.
|
66
|
+
:param link_previews: A little of sender (or server, or gateway)-generated
|
67
|
+
previews of URLs linked in the body.
|
68
|
+
:param archive_only: (only in groups) Do not send this message to user,
|
69
|
+
but store it in the archive. Meant to be used during ``MUC.backfill()``
|
70
|
+
"""
|
71
|
+
if carbon and not hasattr(self, "muc"):
|
72
|
+
if not correction and self.xmpp.store.sent.was_sent_by_user(
|
73
|
+
self.session.user_pk, str(legacy_msg_id)
|
74
|
+
):
|
75
|
+
log.warning(
|
76
|
+
"Carbon message for a message an XMPP has sent? This is a bug! %s",
|
77
|
+
legacy_msg_id,
|
78
|
+
)
|
79
|
+
return
|
80
|
+
if hasattr(self, "muc") and not self.is_user: # type:ignore
|
81
|
+
log.warning(
|
82
|
+
"send_text() called with carbon=True on a participant who is not the user",
|
83
|
+
legacy_msg_id,
|
84
|
+
)
|
85
|
+
self.xmpp.store.sent.set_message(
|
86
|
+
self.session.user_pk,
|
87
|
+
str(legacy_msg_id),
|
88
|
+
self.session.legacy_to_xmpp_msg_id(legacy_msg_id),
|
89
|
+
)
|
90
|
+
hints = self.__default_hints(hints)
|
91
|
+
msg = self._make_message(
|
92
|
+
mbody=body,
|
93
|
+
legacy_msg_id=correction_event_id if correction else legacy_msg_id,
|
94
|
+
when=when,
|
95
|
+
reply_to=reply_to,
|
96
|
+
hints=hints or (),
|
97
|
+
carbon=carbon,
|
98
|
+
thread=thread,
|
99
|
+
link_previews=link_previews,
|
100
|
+
)
|
101
|
+
if correction:
|
102
|
+
msg["replace"]["id"] = self._replace_id(legacy_msg_id)
|
103
|
+
return self._send(
|
104
|
+
msg,
|
105
|
+
archive_only=archive_only,
|
106
|
+
carbon=carbon,
|
107
|
+
legacy_msg_id=legacy_msg_id,
|
108
|
+
**send_kwargs,
|
109
|
+
)
|
110
|
+
|
111
|
+
def correct(
|
112
|
+
self,
|
113
|
+
legacy_msg_id: LegacyMessageType,
|
114
|
+
new_text: str,
|
115
|
+
*,
|
116
|
+
when: Optional[datetime] = None,
|
117
|
+
reply_to: Optional[MessageReference] = None,
|
118
|
+
thread: Optional[LegacyThreadType] = None,
|
119
|
+
hints: Optional[Iterable[ProcessingHint]] = None,
|
120
|
+
carbon=False,
|
121
|
+
archive_only=False,
|
122
|
+
correction_event_id: Optional[LegacyMessageType] = None,
|
123
|
+
link_previews: Optional[list[LinkPreview]] = None,
|
124
|
+
**send_kwargs,
|
125
|
+
):
|
126
|
+
"""
|
127
|
+
Modify a message that was previously sent by this :term:`XMPP Entity`.
|
128
|
+
|
129
|
+
Uses last message correction (:xep:`0308`)
|
130
|
+
|
131
|
+
:param new_text: New content of the message
|
132
|
+
:param legacy_msg_id: The legacy message ID of the message to correct
|
133
|
+
:param when: when the message was sent, for a "delay" tag (:xep:`0203`)
|
134
|
+
:param reply_to: Quote another message (:xep:`0461`)
|
135
|
+
:param hints:
|
136
|
+
:param thread:
|
137
|
+
:param carbon: (only in 1:1) Reflect a message sent to this ``Contact`` by the user.
|
138
|
+
Use this to synchronize outgoing history for legacy official apps.
|
139
|
+
:param archive_only: (only in groups) Do not send this message to user,
|
140
|
+
but store it in the archive. Meant to be used during ``MUC.backfill()``
|
141
|
+
:param correction_event_id: in the case where an ID is associated with the legacy
|
142
|
+
'correction event', specify it here to use it on the XMPP side. If not specified,
|
143
|
+
a random ID will be used.
|
144
|
+
:param link_previews: A little of sender (or server, or gateway)-generated
|
145
|
+
previews of URLs linked in the body.
|
146
|
+
"""
|
147
|
+
self.send_text(
|
148
|
+
new_text,
|
149
|
+
legacy_msg_id,
|
150
|
+
when=when,
|
151
|
+
reply_to=reply_to,
|
152
|
+
hints=hints,
|
153
|
+
carbon=carbon,
|
154
|
+
thread=thread,
|
155
|
+
correction=True,
|
156
|
+
archive_only=archive_only,
|
157
|
+
correction_event_id=correction_event_id,
|
158
|
+
link_previews=link_previews,
|
159
|
+
**send_kwargs,
|
160
|
+
)
|
161
|
+
|
162
|
+
def react(
|
163
|
+
self,
|
164
|
+
legacy_msg_id: LegacyMessageType,
|
165
|
+
emojis: Iterable[str] = (),
|
166
|
+
thread: Optional[LegacyThreadType] = None,
|
167
|
+
**kwargs,
|
168
|
+
):
|
169
|
+
"""
|
170
|
+
Send a reaction (:xep:`0444`) from this :term:`XMPP Entity`.
|
171
|
+
|
172
|
+
:param legacy_msg_id: The message which the reaction refers to.
|
173
|
+
:param emojis: An iterable of emojis used as reactions
|
174
|
+
:param thread:
|
175
|
+
"""
|
176
|
+
msg = self._make_message(
|
177
|
+
hints={"store"}, carbon=kwargs.get("carbon"), thread=thread
|
178
|
+
)
|
179
|
+
xmpp_id = kwargs.pop("xmpp_id", None)
|
180
|
+
if not xmpp_id:
|
181
|
+
xmpp_id = self._legacy_to_xmpp(legacy_msg_id)
|
182
|
+
self.xmpp["xep_0444"].set_reactions(msg, to_id=xmpp_id, reactions=emojis)
|
183
|
+
self._send(msg, **kwargs)
|
184
|
+
|
185
|
+
def retract(
|
186
|
+
self,
|
187
|
+
legacy_msg_id: LegacyMessageType,
|
188
|
+
thread: Optional[LegacyThreadType] = None,
|
189
|
+
**kwargs,
|
190
|
+
):
|
191
|
+
"""
|
192
|
+
Send a message retraction (:XEP:`0424`) from this :term:`XMPP Entity`.
|
193
|
+
|
194
|
+
:param legacy_msg_id: Legacy ID of the message to delete
|
195
|
+
:param thread:
|
196
|
+
"""
|
197
|
+
msg = self._make_message(
|
198
|
+
state=None,
|
199
|
+
hints={"store"},
|
200
|
+
mbody=f"/me retracted the message {legacy_msg_id}",
|
201
|
+
carbon=kwargs.get("carbon"),
|
202
|
+
thread=thread,
|
203
|
+
)
|
204
|
+
msg.enable("fallback")
|
205
|
+
# namespace version mismatch between slidge and slixmpp, update me later
|
206
|
+
msg["fallback"]["for"] = self.xmpp["xep_0424"].namespace[:-1] + "1"
|
207
|
+
msg["retract"]["id"] = msg["replace"]["id"] = self._replace_id(legacy_msg_id)
|
208
|
+
self._send(msg, **kwargs)
|
209
|
+
|
210
|
+
|
211
|
+
log = logging.getLogger(__name__)
|
slidge/core/pubsub.py
CHANGED
@@ -25,8 +25,9 @@ from ..db.store import ContactStore, SlidgeStore
|
|
25
25
|
from .mixins.lock import NamedLockMixin
|
26
26
|
|
27
27
|
if TYPE_CHECKING:
|
28
|
+
from slidge.core.gateway import BaseGateway
|
29
|
+
|
28
30
|
from ..contact.contact import LegacyContact
|
29
|
-
from ..core.gateway.base import BaseGateway
|
30
31
|
|
31
32
|
VCARD4_NAMESPACE = "urn:xmpp:vcard4"
|
32
33
|
|
slidge/core/session.py
CHANGED
@@ -31,6 +31,7 @@ from ..util.types import (
|
|
31
31
|
PseudoPresenceShow,
|
32
32
|
RecipientType,
|
33
33
|
ResourceDict,
|
34
|
+
Sticker,
|
34
35
|
)
|
35
36
|
from ..util.util import deprecated
|
36
37
|
|
@@ -225,6 +226,31 @@ class BaseSession(
|
|
225
226
|
|
226
227
|
send_file = deprecated("BaseSession.send_file", on_file)
|
227
228
|
|
229
|
+
async def on_sticker(
|
230
|
+
self,
|
231
|
+
chat: RecipientType,
|
232
|
+
sticker: Sticker,
|
233
|
+
*,
|
234
|
+
reply_to_msg_id: Optional[LegacyMessageType] = None,
|
235
|
+
reply_to_fallback_text: Optional[str] = None,
|
236
|
+
reply_to: Optional[Union["LegacyContact", "LegacyParticipant"]] = None,
|
237
|
+
thread: Optional[LegacyThreadType] = None,
|
238
|
+
) -> Optional[LegacyMessageType]:
|
239
|
+
"""
|
240
|
+
Triggered when the user sends a file using HTTP Upload (:xep:`0363`)
|
241
|
+
|
242
|
+
:param chat: See :meth:`.BaseSession.on_text`
|
243
|
+
:param sticker: The sticker sent by the user.
|
244
|
+
:param reply_to_msg_id: See :meth:`.BaseSession.on_text`
|
245
|
+
:param reply_to_fallback_text: See :meth:`.BaseSession.on_text`
|
246
|
+
:param reply_to: See :meth:`.BaseSession.on_text`
|
247
|
+
:param thread:
|
248
|
+
|
249
|
+
:return: An ID of some sort that can be used later to ack and mark the message
|
250
|
+
as read by the user
|
251
|
+
"""
|
252
|
+
raise NotImplementedError
|
253
|
+
|
228
254
|
async def on_active(
|
229
255
|
self, chat: RecipientType, thread: Optional[LegacyThreadType] = None
|
230
256
|
):
|
@@ -729,8 +755,8 @@ class BaseSession(
|
|
729
755
|
self.xmpp.re_login(self)
|
730
756
|
|
731
757
|
async def get_contact_or_group_or_participant(self, jid: JID, create=True):
|
732
|
-
if
|
733
|
-
return
|
758
|
+
if (contact := self.contacts.by_jid_only_if_exists(jid)) is not None:
|
759
|
+
return contact
|
734
760
|
if (muc := self.bookmarks.by_jid_only_if_exists(JID(jid.bare))) is not None:
|
735
761
|
return await self.__get_muc_or_participant(muc, jid)
|
736
762
|
else:
|
@@ -0,0 +1,83 @@
|
|
1
|
+
"""Remove bogus unique constraints on room table
|
2
|
+
|
3
|
+
Revision ID: 15b0bd83407a
|
4
|
+
Revises: 45c24cc73c91
|
5
|
+
Create Date: 2024-08-28 06:57:25.022994
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
from typing import Sequence, Union
|
10
|
+
|
11
|
+
import sqlalchemy as sa
|
12
|
+
from alembic import op
|
13
|
+
|
14
|
+
import slidge.db.meta
|
15
|
+
|
16
|
+
# revision identifiers, used by Alembic.
|
17
|
+
revision: str = "15b0bd83407a"
|
18
|
+
down_revision: Union[str, None] = "45c24cc73c91"
|
19
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
20
|
+
depends_on: Union[str, Sequence[str], None] = None
|
21
|
+
|
22
|
+
meta = sa.MetaData()
|
23
|
+
room_table = sa.Table(
|
24
|
+
"room",
|
25
|
+
meta,
|
26
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
27
|
+
sa.Column("user_account_id", sa.Integer(), nullable=False),
|
28
|
+
sa.Column("legacy_id", sa.String(), nullable=False),
|
29
|
+
sa.Column("jid", slidge.db.meta.JIDType(), nullable=False),
|
30
|
+
sa.Column("avatar_id", sa.Integer(), nullable=True),
|
31
|
+
sa.Column("name", sa.String(), nullable=True),
|
32
|
+
sa.Column("description", sa.String(), nullable=True),
|
33
|
+
sa.Column("subject", sa.String(), nullable=True),
|
34
|
+
sa.Column("subject_date", sa.DateTime(), nullable=True),
|
35
|
+
sa.Column("subject_setter", sa.String(), nullable=True),
|
36
|
+
sa.Column("n_participants", sa.Integer(), nullable=True),
|
37
|
+
sa.Column(
|
38
|
+
"muc_type",
|
39
|
+
sa.Enum("GROUP", "CHANNEL", "CHANNEL_NON_ANONYMOUS", name="muctype"),
|
40
|
+
nullable=True,
|
41
|
+
),
|
42
|
+
sa.Column("user_nick", sa.String(), nullable=True),
|
43
|
+
sa.Column("user_resources", sa.String(), nullable=True),
|
44
|
+
sa.Column("participants_filled", sa.Boolean(), nullable=False),
|
45
|
+
sa.Column("history_filled", sa.Boolean(), nullable=False),
|
46
|
+
sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
|
47
|
+
sa.Column("updated", sa.Boolean(), nullable=False),
|
48
|
+
sa.Column("avatar_legacy_id", sa.String(), nullable=True),
|
49
|
+
sa.ForeignKeyConstraint(
|
50
|
+
["avatar_id"],
|
51
|
+
["avatar.id"],
|
52
|
+
),
|
53
|
+
sa.ForeignKeyConstraint(
|
54
|
+
["user_account_id"],
|
55
|
+
["user_account.id"],
|
56
|
+
),
|
57
|
+
sa.PrimaryKeyConstraint("id"),
|
58
|
+
)
|
59
|
+
|
60
|
+
|
61
|
+
def upgrade() -> None:
|
62
|
+
with op.batch_alter_table(
|
63
|
+
"room",
|
64
|
+
schema=None,
|
65
|
+
# without copy_from, the newly created table keeps the constraints
|
66
|
+
# we actually want to ditch.
|
67
|
+
copy_from=room_table,
|
68
|
+
) as batch_op:
|
69
|
+
batch_op.create_unique_constraint(
|
70
|
+
"uq_room_user_account_id_jid", ["user_account_id", "jid"]
|
71
|
+
)
|
72
|
+
batch_op.create_unique_constraint(
|
73
|
+
"uq_room_user_account_id_legacy_id", ["user_account_id", "legacy_id"]
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
def downgrade() -> None:
|
78
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
79
|
+
with op.batch_alter_table("room", schema=None) as batch_op:
|
80
|
+
batch_op.drop_constraint("uq_room_user_account_id_legacy_id", type_="unique")
|
81
|
+
batch_op.drop_constraint("uq_room_user_account_id_jid", type_="unique")
|
82
|
+
|
83
|
+
# ### end Alembic commands ###
|
@@ -0,0 +1,42 @@
|
|
1
|
+
"""Add BoB
|
2
|
+
|
3
|
+
Revision ID: 45c24cc73c91
|
4
|
+
Revises: 3071e0fa69d4
|
5
|
+
Create Date: 2024-08-01 22:30:07.073935
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
from typing import Sequence, Union
|
10
|
+
|
11
|
+
import sqlalchemy as sa
|
12
|
+
from alembic import op
|
13
|
+
|
14
|
+
# revision identifiers, used by Alembic.
|
15
|
+
revision: str = "45c24cc73c91"
|
16
|
+
down_revision: Union[str, None] = "3071e0fa69d4"
|
17
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
18
|
+
depends_on: Union[str, Sequence[str], None] = None
|
19
|
+
|
20
|
+
|
21
|
+
def upgrade() -> None:
|
22
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
23
|
+
op.create_table(
|
24
|
+
"bob",
|
25
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
26
|
+
sa.Column("file_name", sa.String(), nullable=False),
|
27
|
+
sa.Column("sha_1", sa.String(), nullable=False),
|
28
|
+
sa.Column("sha_256", sa.String(), nullable=False),
|
29
|
+
sa.Column("sha_512", sa.String(), nullable=False),
|
30
|
+
sa.Column("content_type", sa.String(), nullable=False),
|
31
|
+
sa.PrimaryKeyConstraint("id"),
|
32
|
+
sa.UniqueConstraint("sha_1"),
|
33
|
+
sa.UniqueConstraint("sha_256"),
|
34
|
+
sa.UniqueConstraint("sha_512"),
|
35
|
+
)
|
36
|
+
# ### end Alembic commands ###
|
37
|
+
|
38
|
+
|
39
|
+
def downgrade() -> None:
|
40
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
41
|
+
op.drop_table("bob")
|
42
|
+
# ### end Alembic commands ###
|
@@ -4,8 +4,12 @@ Revision ID: 5bd48bfdffa2
|
|
4
4
|
Revises: b64b1a793483
|
5
5
|
Create Date: 2024-07-24 10:29:23.467851
|
6
6
|
|
7
|
+
Broken; fixed by "Remove bogus unique constraints on room table",
|
8
|
+
rev 15b0bd83407a.
|
9
|
+
|
7
10
|
"""
|
8
11
|
|
12
|
+
import logging
|
9
13
|
from typing import Sequence, Union
|
10
14
|
|
11
15
|
from alembic import op
|
@@ -26,6 +30,8 @@ def upgrade() -> None:
|
|
26
30
|
schema=None,
|
27
31
|
# without copy_from, the newly created table keeps the constraints
|
28
32
|
# we actually want to ditch.
|
33
|
+
# LATER EDIT: this actually does not work, I should have copied the
|
34
|
+
# schema in here.
|
29
35
|
copy_from=Room.__table__, # type:ignore
|
30
36
|
) as batch_op:
|
31
37
|
batch_op.create_unique_constraint(
|
@@ -35,9 +41,11 @@ def upgrade() -> None:
|
|
35
41
|
"uq_room_user_account_id_legacy_id", ["user_account_id", "legacy_id"]
|
36
42
|
)
|
37
43
|
except Exception:
|
38
|
-
#
|
44
|
+
# This only works when upgrading rev by rev because I messed up. It
|
39
45
|
# wouldn't be necessary if the constraint was named in the first place,
|
40
46
|
# cf https://alembic.sqlalchemy.org/en/latest/naming.html
|
47
|
+
# This is fixed by rev 15b0bd83407a
|
48
|
+
log.info("Skipping")
|
41
49
|
pass
|
42
50
|
|
43
51
|
|
@@ -48,3 +56,6 @@ def downgrade() -> None:
|
|
48
56
|
batch_op.drop_constraint("uq_room_user_account_id_jid", type_="unique")
|
49
57
|
|
50
58
|
# ### end Alembic commands ###
|
59
|
+
|
60
|
+
|
61
|
+
log = logging.getLogger(__name__)
|