slidge 0.2.0a9__py3-none-any.whl → 0.2.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. slidge/__main__.py +2 -3
  2. slidge/__version__.py +1 -1
  3. slidge/command/adhoc.py +1 -1
  4. slidge/command/base.py +4 -4
  5. slidge/command/user.py +5 -1
  6. slidge/contact/roster.py +9 -0
  7. slidge/core/config.py +0 -3
  8. slidge/core/dispatcher/__init__.py +3 -0
  9. slidge/core/{gateway → dispatcher}/caps.py +6 -4
  10. slidge/core/{gateway → dispatcher}/disco.py +11 -17
  11. slidge/core/dispatcher/message/__init__.py +10 -0
  12. slidge/core/dispatcher/message/chat_state.py +40 -0
  13. slidge/core/dispatcher/message/marker.py +62 -0
  14. slidge/core/dispatcher/message/message.py +397 -0
  15. slidge/core/dispatcher/muc/__init__.py +12 -0
  16. slidge/core/dispatcher/muc/admin.py +98 -0
  17. slidge/core/{gateway → dispatcher/muc}/mam.py +26 -15
  18. slidge/core/dispatcher/muc/misc.py +121 -0
  19. slidge/core/dispatcher/muc/owner.py +96 -0
  20. slidge/core/{gateway → dispatcher/muc}/ping.py +10 -15
  21. slidge/core/dispatcher/presence.py +177 -0
  22. slidge/core/{gateway → dispatcher}/registration.py +23 -2
  23. slidge/core/{gateway → dispatcher}/search.py +9 -14
  24. slidge/core/dispatcher/session_dispatcher.py +84 -0
  25. slidge/core/dispatcher/util.py +174 -0
  26. slidge/core/{gateway/vcard_temp.py → dispatcher/vcard.py} +26 -12
  27. slidge/core/{gateway/base.py → gateway.py} +42 -137
  28. slidge/core/mixins/attachment.py +24 -8
  29. slidge/core/mixins/base.py +2 -2
  30. slidge/core/mixins/lock.py +10 -8
  31. slidge/core/mixins/message.py +9 -203
  32. slidge/core/mixins/message_text.py +211 -0
  33. slidge/core/pubsub.py +2 -1
  34. slidge/core/session.py +28 -2
  35. slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +83 -0
  36. slidge/db/alembic/versions/45c24cc73c91_add_bob.py +42 -0
  37. slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +12 -1
  38. slidge/db/models.py +16 -1
  39. slidge/db/store.py +144 -11
  40. slidge/group/bookmarks.py +23 -1
  41. slidge/group/participant.py +5 -5
  42. slidge/group/room.py +10 -1
  43. slidge/{core/gateway → slixfix}/delivery_receipt.py +1 -1
  44. slidge/util/test.py +9 -5
  45. slidge/util/types.py +6 -0
  46. slidge/util/util.py +5 -2
  47. {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/METADATA +2 -1
  48. {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/RECORD +51 -40
  49. slidge-0.2.0b0.dist-info/entry_points.txt +3 -0
  50. slidge/core/gateway/__init__.py +0 -3
  51. slidge/core/gateway/muc_admin.py +0 -35
  52. slidge/core/gateway/presence.py +0 -95
  53. slidge/core/gateway/session_dispatcher.py +0 -895
  54. slidge-0.2.0a9.dist-info/entry_points.txt +0 -3
  55. {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/LICENSE +0 -0
  56. {slidge-0.2.0a9.dist-info → slidge-0.2.0b0.dist-info}/WHEEL +0 -0
@@ -1,23 +1,15 @@
1
1
  import logging
2
2
  import uuid
3
3
  import warnings
4
- from datetime import datetime
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
- def __default_hints(self, hints: Optional[Iterable[ProcessingHint]] = None):
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 not i:
356
- i = str(uuid.uuid4())
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 jid.bare in (contacts := self.contacts.known_contacts(only_friends=False)):
733
- return contacts[jid.bare]
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
- # happens when migration is not needed
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__)