slidge 0.2.11__py3-none-any.whl → 0.3.0__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.
- slidge/__init__.py +5 -2
- slidge/command/adhoc.py +9 -3
- slidge/command/admin.py +16 -12
- slidge/command/base.py +16 -12
- slidge/command/chat_command.py +25 -16
- slidge/command/user.py +7 -8
- slidge/contact/contact.py +123 -210
- slidge/contact/roster.py +108 -105
- slidge/core/config.py +2 -43
- slidge/core/dispatcher/caps.py +9 -2
- slidge/core/dispatcher/disco.py +13 -3
- slidge/core/dispatcher/message/__init__.py +1 -1
- slidge/core/dispatcher/message/chat_state.py +17 -8
- slidge/core/dispatcher/message/marker.py +7 -5
- slidge/core/dispatcher/message/message.py +120 -93
- slidge/core/dispatcher/muc/__init__.py +1 -1
- slidge/core/dispatcher/muc/admin.py +4 -4
- slidge/core/dispatcher/muc/mam.py +10 -6
- slidge/core/dispatcher/muc/misc.py +4 -2
- slidge/core/dispatcher/muc/owner.py +5 -3
- slidge/core/dispatcher/muc/ping.py +3 -1
- slidge/core/dispatcher/presence.py +26 -15
- slidge/core/dispatcher/registration.py +20 -12
- slidge/core/dispatcher/search.py +7 -3
- slidge/core/dispatcher/session_dispatcher.py +13 -5
- slidge/core/dispatcher/util.py +37 -27
- slidge/core/dispatcher/vcard.py +7 -4
- slidge/core/gateway.py +177 -87
- slidge/core/mixins/__init__.py +1 -11
- slidge/core/mixins/attachment.py +200 -147
- slidge/core/mixins/avatar.py +105 -177
- slidge/core/mixins/base.py +3 -1
- slidge/core/mixins/db.py +50 -2
- slidge/core/mixins/disco.py +1 -1
- slidge/core/mixins/message.py +19 -17
- slidge/core/mixins/message_maker.py +29 -15
- slidge/core/mixins/message_text.py +67 -30
- slidge/core/mixins/presence.py +94 -37
- slidge/core/pubsub.py +42 -47
- slidge/core/session.py +95 -60
- slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +361 -0
- slidge/db/avatar.py +150 -119
- slidge/db/meta.py +33 -22
- slidge/db/models.py +69 -117
- slidge/db/store.py +414 -1094
- slidge/group/archive.py +65 -55
- slidge/group/bookmarks.py +96 -59
- slidge/group/participant.py +150 -144
- slidge/group/room.py +351 -328
- slidge/main.py +34 -22
- slidge/migration.py +17 -29
- slidge/slixfix/__init__.py +20 -4
- slidge/slixfix/delivery_receipt.py +6 -4
- slidge/slixfix/link_preview/link_preview.py +1 -1
- slidge/slixfix/link_preview/stanza.py +1 -1
- slidge/slixfix/roster.py +5 -7
- slidge/slixfix/xep_0077/register.py +8 -8
- slidge/slixfix/xep_0077/stanza.py +7 -7
- slidge/slixfix/xep_0100/gateway.py +12 -13
- slidge/slixfix/xep_0153/vcard_avatar.py +1 -1
- slidge/slixfix/xep_0292/vcard4.py +12 -2
- slidge/util/archive_msg.py +11 -5
- slidge/util/conf.py +27 -21
- slidge/util/jid_escaping.py +1 -1
- slidge/{core/mixins → util}/lock.py +6 -6
- slidge/util/test.py +30 -29
- slidge/util/types.py +24 -18
- slidge/util/util.py +26 -22
- {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/METADATA +1 -1
- slidge-0.3.0.dist-info/RECORD +95 -0
- {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/WHEEL +1 -1
- slidge/db/alembic/versions/04cf35e3cf85_add_participant_nickname_no_illegal.py +0 -33
- slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -36
- slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -85
- slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -36
- slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -37
- slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -41
- slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -52
- slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -42
- slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -61
- slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -48
- slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -43
- slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -139
- slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -50
- slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -79
- slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -214
- slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -52
- slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -34
- slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -26
- slidge-0.2.11.dist-info/RECORD +0 -112
- {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/entry_points.txt +0 -0
- {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/top_level.txt +0 -0
slidge/db/models.py
CHANGED
@@ -6,24 +6,13 @@ from typing import Optional
|
|
6
6
|
import sqlalchemy as sa
|
7
7
|
from slixmpp import JID
|
8
8
|
from slixmpp.types import MucAffiliation, MucRole
|
9
|
-
from sqlalchemy import ForeignKey, Index, UniqueConstraint
|
10
|
-
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
9
|
+
from sqlalchemy import JSON, ForeignKey, Index, UniqueConstraint
|
10
|
+
from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship
|
11
11
|
|
12
12
|
from ..util.types import ClientType, MucType
|
13
13
|
from .meta import Base, JSONSerializable, JSONSerializableTypes
|
14
14
|
|
15
15
|
|
16
|
-
class XmppToLegacyEnum(IntEnum):
|
17
|
-
"""
|
18
|
-
XMPP-client generated IDs, used in the XmppToLegacyIds table to keep track
|
19
|
-
of corresponding legacy IDs
|
20
|
-
"""
|
21
|
-
|
22
|
-
DM = 1
|
23
|
-
GROUP_CHAT = 2
|
24
|
-
THREAD = 3
|
25
|
-
|
26
|
-
|
27
16
|
class ArchivedMessageSource(IntEnum):
|
28
17
|
"""
|
29
18
|
Whether an archived message comes from ``LegacyMUC.backfill()`` or was received
|
@@ -63,16 +52,7 @@ class GatewayUser(Base):
|
|
63
52
|
rooms: Mapped[list["Room"]] = relationship(
|
64
53
|
back_populates="user", cascade="all, delete-orphan"
|
65
54
|
)
|
66
|
-
xmpp_to_legacy: Mapped[list["XmppToLegacyIds"]] = relationship(
|
67
|
-
cascade="all, delete-orphan"
|
68
|
-
)
|
69
55
|
attachments: Mapped[list["Attachment"]] = relationship(cascade="all, delete-orphan")
|
70
|
-
multi_legacy: Mapped[list["LegacyIdsMulti"]] = relationship(
|
71
|
-
cascade="all, delete-orphan"
|
72
|
-
)
|
73
|
-
multi_xmpp: Mapped[list["XmppIdsMulti"]] = relationship(
|
74
|
-
cascade="all, delete-orphan"
|
75
|
-
)
|
76
56
|
|
77
57
|
def __repr__(self) -> str:
|
78
58
|
return f"User(id={self.id!r}, jid={self.jid!r})"
|
@@ -109,11 +89,12 @@ class Avatar(Base):
|
|
109
89
|
|
110
90
|
id: Mapped[int] = mapped_column(primary_key=True)
|
111
91
|
|
112
|
-
filename: Mapped[str] = mapped_column(unique=True)
|
113
92
|
hash: Mapped[str] = mapped_column(unique=True)
|
114
93
|
height: Mapped[int] = mapped_column()
|
115
94
|
width: Mapped[int] = mapped_column()
|
116
95
|
|
96
|
+
legacy_id: Mapped[Optional[str]] = mapped_column(unique=True, nullable=True)
|
97
|
+
|
117
98
|
# this is only used when avatars are available as HTTP URLs and do not
|
118
99
|
# have a legacy_id
|
119
100
|
url: Mapped[Optional[str]] = mapped_column(default=None)
|
@@ -137,13 +118,17 @@ class Contact(Base):
|
|
137
118
|
|
138
119
|
id: Mapped[int] = mapped_column(primary_key=True)
|
139
120
|
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
140
|
-
user: Mapped[GatewayUser] = relationship(back_populates="contacts")
|
121
|
+
user: Mapped[GatewayUser] = relationship(lazy=True, back_populates="contacts")
|
141
122
|
legacy_id: Mapped[str] = mapped_column(nullable=False)
|
142
123
|
|
143
124
|
jid: Mapped[JID] = mapped_column()
|
144
125
|
|
145
|
-
avatar_id: Mapped[int] = mapped_column(
|
146
|
-
|
126
|
+
avatar_id: Mapped[Optional[int]] = mapped_column(
|
127
|
+
ForeignKey("avatar.id"), nullable=True
|
128
|
+
)
|
129
|
+
avatar: Mapped[Optional[Avatar]] = relationship(
|
130
|
+
lazy=False, back_populates="contacts"
|
131
|
+
)
|
147
132
|
|
148
133
|
nick: Mapped[Optional[str]] = mapped_column(nullable=True)
|
149
134
|
|
@@ -170,10 +155,13 @@ class Contact(Base):
|
|
170
155
|
|
171
156
|
participants: Mapped[list["Participant"]] = relationship(back_populates="contact")
|
172
157
|
|
173
|
-
avatar_legacy_id: Mapped[Optional[str]] = mapped_column(nullable=True)
|
174
|
-
|
175
158
|
client_type: Mapped[ClientType] = mapped_column(nullable=False, default="pc")
|
176
159
|
|
160
|
+
messages: Mapped[list["DirectMessages"]] = relationship(
|
161
|
+
cascade="all, delete-orphan"
|
162
|
+
)
|
163
|
+
threads: Mapped[list["DirectThreads"]] = relationship(cascade="all, delete-orphan")
|
164
|
+
|
177
165
|
|
178
166
|
class ContactSent(Base):
|
179
167
|
"""
|
@@ -207,13 +195,15 @@ class Room(Base):
|
|
207
195
|
__tablename__ = "room"
|
208
196
|
id: Mapped[int] = mapped_column(primary_key=True)
|
209
197
|
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
210
|
-
user: Mapped[GatewayUser] = relationship(back_populates="rooms")
|
198
|
+
user: Mapped[GatewayUser] = relationship(lazy=True, back_populates="rooms")
|
211
199
|
legacy_id: Mapped[str] = mapped_column(nullable=False)
|
212
200
|
|
213
201
|
jid: Mapped[JID] = mapped_column(nullable=False)
|
214
202
|
|
215
|
-
avatar_id: Mapped[int] = mapped_column(
|
216
|
-
|
203
|
+
avatar_id: Mapped[Optional[int]] = mapped_column(
|
204
|
+
ForeignKey("avatar.id"), nullable=True
|
205
|
+
)
|
206
|
+
avatar: Mapped[Optional[Avatar]] = relationship(lazy=False, back_populates="rooms")
|
217
207
|
|
218
208
|
name: Mapped[Optional[str]] = mapped_column(nullable=True)
|
219
209
|
description: Mapped[Optional[str]] = mapped_column(nullable=True)
|
@@ -223,7 +213,7 @@ class Room(Base):
|
|
223
213
|
|
224
214
|
n_participants: Mapped[Optional[int]] = mapped_column(default=None)
|
225
215
|
|
226
|
-
muc_type: Mapped[
|
216
|
+
muc_type: Mapped[MucType] = mapped_column(default=MucType.CHANNEL)
|
227
217
|
|
228
218
|
user_nick: Mapped[Optional[str]] = mapped_column()
|
229
219
|
user_resources: Mapped[Optional[str]] = mapped_column(nullable=True)
|
@@ -240,12 +230,13 @@ class Room(Base):
|
|
240
230
|
cascade="all, delete-orphan",
|
241
231
|
)
|
242
232
|
|
243
|
-
avatar_legacy_id: Mapped[Optional[str]] = mapped_column(nullable=True)
|
244
|
-
|
245
233
|
archive: Mapped[list["ArchivedMessage"]] = relationship(
|
246
234
|
cascade="all, delete-orphan"
|
247
235
|
)
|
248
236
|
|
237
|
+
messages: Mapped[list["GroupMessages"]] = relationship(cascade="all, delete-orphan")
|
238
|
+
threads: Mapped[list["GroupThreads"]] = relationship(cascade="all, delete-orphan")
|
239
|
+
|
249
240
|
|
250
241
|
class ArchivedMessage(Base):
|
251
242
|
"""
|
@@ -267,23 +258,40 @@ class ArchivedMessage(Base):
|
|
267
258
|
stanza: Mapped[str] = mapped_column(nullable=False)
|
268
259
|
|
269
260
|
|
270
|
-
class
|
261
|
+
class _LegacyToXmppIdsBase:
|
271
262
|
"""
|
272
|
-
XMPP-client generated IDs, and mapping to the corresponding legacy IDs
|
263
|
+
XMPP-client generated IDs, and mapping to the corresponding legacy IDs.
|
264
|
+
|
265
|
+
A single legacy ID can map to several XMPP ids.
|
273
266
|
"""
|
274
267
|
|
275
|
-
__tablename__ = "xmpp_to_legacy_ids"
|
276
|
-
__table_args__ = (
|
277
|
-
Index("xmpp_legacy", "user_account_id", "xmpp_id", "legacy_id", unique=True),
|
278
|
-
)
|
279
268
|
id: Mapped[int] = mapped_column(primary_key=True)
|
280
|
-
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
281
|
-
user: Mapped[GatewayUser] = relationship(back_populates="xmpp_to_legacy")
|
282
|
-
|
283
|
-
xmpp_id: Mapped[str] = mapped_column(nullable=False)
|
284
269
|
legacy_id: Mapped[str] = mapped_column(nullable=False)
|
270
|
+
xmpp_id: Mapped[str] = mapped_column(nullable=False)
|
271
|
+
|
272
|
+
|
273
|
+
class DirectMessages(_LegacyToXmppIdsBase, Base):
|
274
|
+
__tablename__ = "direct_msg"
|
275
|
+
__table_args__ = (Index("ix_direct_msg_legacy_id", "legacy_id", "foreign_key"),)
|
276
|
+
foreign_key: Mapped[int] = mapped_column(ForeignKey("contact.id"), nullable=False)
|
277
|
+
|
278
|
+
|
279
|
+
class GroupMessages(_LegacyToXmppIdsBase, Base):
|
280
|
+
__tablename__ = "group_msg"
|
281
|
+
__table_args__ = (Index("ix_group_msg_legacy_id", "legacy_id", "foreign_key"),)
|
282
|
+
foreign_key: Mapped[int] = mapped_column(ForeignKey("room.id"), nullable=False)
|
285
283
|
|
286
|
-
|
284
|
+
|
285
|
+
class DirectThreads(_LegacyToXmppIdsBase, Base):
|
286
|
+
__tablename__ = "direct_thread"
|
287
|
+
__table_args__ = (Index("ix_direct_direct_thread_id", "legacy_id", "foreign_key"),)
|
288
|
+
foreign_key: Mapped[int] = mapped_column(ForeignKey("contact.id"), nullable=False)
|
289
|
+
|
290
|
+
|
291
|
+
class GroupThreads(_LegacyToXmppIdsBase, Base):
|
292
|
+
__tablename__ = "group_thread"
|
293
|
+
__table_args__ = (Index("ix_direct_group_thread_id", "legacy_id", "foreign_key"),)
|
294
|
+
foreign_key: Mapped[int] = mapped_column(ForeignKey("room.id"), nullable=False)
|
287
295
|
|
288
296
|
|
289
297
|
class Attachment(Base):
|
@@ -292,6 +300,7 @@ class Attachment(Base):
|
|
292
300
|
"""
|
293
301
|
|
294
302
|
__tablename__ = "attachment"
|
303
|
+
__table_args__ = (UniqueConstraint("user_account_id", "legacy_file_id"),)
|
295
304
|
|
296
305
|
id: Mapped[int] = mapped_column(primary_key=True)
|
297
306
|
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
@@ -303,81 +312,26 @@ class Attachment(Base):
|
|
303
312
|
sfs: Mapped[Optional[str]] = mapped_column()
|
304
313
|
|
305
314
|
|
306
|
-
class LegacyIdsMulti(Base):
|
307
|
-
"""
|
308
|
-
Legacy messages with multiple attachments are split as several XMPP messages,
|
309
|
-
this table and the next maps a single legacy ID to multiple XMPP IDs.
|
310
|
-
"""
|
311
|
-
|
312
|
-
__tablename__ = "legacy_ids_multi"
|
313
|
-
__table_args__ = (
|
314
|
-
Index(
|
315
|
-
"legacy_ids_multi_user_account_id_legacy_id",
|
316
|
-
"user_account_id",
|
317
|
-
"legacy_id",
|
318
|
-
unique=True,
|
319
|
-
),
|
320
|
-
)
|
321
|
-
id: Mapped[int] = mapped_column(primary_key=True)
|
322
|
-
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
323
|
-
|
324
|
-
legacy_id: Mapped[str] = mapped_column(nullable=False)
|
325
|
-
xmpp_ids: Mapped[list["XmppIdsMulti"]] = relationship(
|
326
|
-
back_populates="legacy_ids_multi", cascade="all, delete-orphan"
|
327
|
-
)
|
328
|
-
|
329
|
-
|
330
|
-
class XmppIdsMulti(Base):
|
331
|
-
__tablename__ = "xmpp_ids_multi"
|
332
|
-
__table_args__ = (
|
333
|
-
Index(
|
334
|
-
"legacy_ids_multi_user_account_id_xmpp_id",
|
335
|
-
"user_account_id",
|
336
|
-
"xmpp_id",
|
337
|
-
unique=True,
|
338
|
-
),
|
339
|
-
)
|
340
|
-
id: Mapped[int] = mapped_column(primary_key=True)
|
341
|
-
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
342
|
-
|
343
|
-
xmpp_id: Mapped[str] = mapped_column(nullable=False)
|
344
|
-
|
345
|
-
legacy_ids_multi_id: Mapped[int] = mapped_column(ForeignKey("legacy_ids_multi.id"))
|
346
|
-
legacy_ids_multi: Mapped[LegacyIdsMulti] = relationship(back_populates="xmpp_ids")
|
347
|
-
|
348
|
-
|
349
|
-
participant_hats = sa.Table(
|
350
|
-
"participant_hats",
|
351
|
-
Base.metadata,
|
352
|
-
sa.Column("participant_id", ForeignKey("participant.id"), primary_key=True),
|
353
|
-
sa.Column("hat_id", ForeignKey("hat.id"), primary_key=True),
|
354
|
-
)
|
355
|
-
|
356
|
-
|
357
|
-
class Hat(Base):
|
358
|
-
__tablename__ = "hat"
|
359
|
-
__table_args__ = (UniqueConstraint("title", "uri"),)
|
360
|
-
|
361
|
-
id: Mapped[int] = mapped_column(primary_key=True)
|
362
|
-
title: Mapped[str] = mapped_column()
|
363
|
-
uri: Mapped[str] = mapped_column()
|
364
|
-
participants: Mapped[list["Participant"]] = relationship(
|
365
|
-
secondary=participant_hats, back_populates="hats"
|
366
|
-
)
|
367
|
-
|
368
|
-
|
369
315
|
class Participant(Base):
|
370
316
|
__tablename__ = "participant"
|
317
|
+
__table_args__ = (
|
318
|
+
UniqueConstraint("room_id", "resource"),
|
319
|
+
UniqueConstraint("room_id", "contact_id"),
|
320
|
+
)
|
371
321
|
|
372
322
|
id: Mapped[int] = mapped_column(primary_key=True)
|
373
323
|
|
374
324
|
room_id: Mapped[int] = mapped_column(ForeignKey("room.id"), nullable=False)
|
375
325
|
room: Mapped[Room] = relationship(
|
376
|
-
back_populates="participants", primaryjoin=Room.id == room_id
|
326
|
+
lazy=False, back_populates="participants", primaryjoin=Room.id == room_id
|
377
327
|
)
|
378
328
|
|
379
|
-
contact_id: Mapped[int] = mapped_column(
|
380
|
-
|
329
|
+
contact_id: Mapped[Optional[int]] = mapped_column(
|
330
|
+
ForeignKey("contact.id"), nullable=True
|
331
|
+
)
|
332
|
+
contact: Mapped[Optional[Contact]] = relationship(
|
333
|
+
lazy=False, back_populates="participants"
|
334
|
+
)
|
381
335
|
|
382
336
|
is_user: Mapped[bool] = mapped_column(default=False)
|
383
337
|
|
@@ -386,13 +340,11 @@ class Participant(Base):
|
|
386
340
|
|
387
341
|
presence_sent: Mapped[bool] = mapped_column(default=False)
|
388
342
|
|
389
|
-
resource: Mapped[
|
390
|
-
nickname: Mapped[str] = mapped_column(nullable=
|
391
|
-
nickname_no_illegal: Mapped[str] = mapped_column(nullable=
|
343
|
+
resource: Mapped[str] = mapped_column(nullable=False)
|
344
|
+
nickname: Mapped[str] = mapped_column(nullable=False, default=None)
|
345
|
+
nickname_no_illegal: Mapped[str] = mapped_column(nullable=False, default=None)
|
392
346
|
|
393
|
-
hats: Mapped[list[
|
394
|
-
secondary=participant_hats, back_populates="participants"
|
395
|
-
)
|
347
|
+
hats: Mapped[list[tuple[str, str]]] = mapped_column(JSON, default=list)
|
396
348
|
|
397
349
|
extra_attributes: Mapped[Optional[JSONSerializable]] = mapped_column(default=None)
|
398
350
|
|