slidge 0.2.0a1__py3-none-any.whl → 0.2.0a3__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/__version__.py +1 -1
- slidge/contact/contact.py +57 -6
- slidge/core/gateway/base.py +0 -2
- slidge/core/gateway/session_dispatcher.py +19 -0
- slidge/core/gateway/vcard_temp.py +2 -2
- slidge/core/pubsub.py +11 -9
- slidge/db/alembic/__init__.py +0 -0
- slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +44 -0
- slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +43 -0
- slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +13 -1
- slidge/db/meta.py +7 -0
- slidge/db/models.py +12 -2
- slidge/db/store.py +14 -1
- slidge/group/room.py +8 -2
- slidge/main.py +0 -4
- slidge/slixfix/roster.py +4 -2
- slidge/slixfix/xep_0292/vcard4.py +1 -90
- slidge/util/test.py +1 -1
- {slidge-0.2.0a1.dist-info → slidge-0.2.0a3.dist-info}/METADATA +1 -1
- {slidge-0.2.0a1.dist-info → slidge-0.2.0a3.dist-info}/RECORD +24 -21
- /slidge/{util/db.py → db/alembic/old_user_store.py} +0 -0
- {slidge-0.2.0a1.dist-info → slidge-0.2.0a3.dist-info}/LICENSE +0 -0
- {slidge-0.2.0a1.dist-info → slidge-0.2.0a3.dist-info}/WHEEL +0 -0
- {slidge-0.2.0a1.dist-info → slidge-0.2.0a3.dist-info}/entry_points.txt +0 -0
slidge/__version__.py
CHANGED
slidge/contact/contact.py
CHANGED
@@ -3,6 +3,7 @@ import logging
|
|
3
3
|
import warnings
|
4
4
|
from datetime import date
|
5
5
|
from typing import TYPE_CHECKING, Generic, Iterable, Optional, Self, Union
|
6
|
+
from xml.etree import ElementTree as ET
|
6
7
|
|
7
8
|
from slixmpp import JID, Message, Presence
|
8
9
|
from slixmpp.exceptions import IqError
|
@@ -120,10 +121,21 @@ class LegacyContact(
|
|
120
121
|
self.xmpp = session.xmpp
|
121
122
|
self.jid = JID(self.jid_username + "@" + self.xmpp.boundjid.bare)
|
122
123
|
self.jid.resource = self.RESOURCE
|
123
|
-
self.log = logging.getLogger(
|
124
|
+
self.log = logging.getLogger(self.jid.bare)
|
125
|
+
self._set_logger_name()
|
124
126
|
self._is_friend: bool = False
|
125
127
|
self._added_to_roster = False
|
126
128
|
self._caps_ver: str | None = None
|
129
|
+
self._vcard_fetched = False
|
130
|
+
self._vcard: str | None = None
|
131
|
+
|
132
|
+
async def get_vcard(self) -> VCard4 | None:
|
133
|
+
if not self._vcard_fetched:
|
134
|
+
await self.fetch_vcard()
|
135
|
+
if self._vcard is None:
|
136
|
+
return None
|
137
|
+
|
138
|
+
return VCard4(xml=ET.fromstring(self._vcard))
|
127
139
|
|
128
140
|
@property
|
129
141
|
def is_friend(self):
|
@@ -136,6 +148,7 @@ class LegacyContact(
|
|
136
148
|
self._is_friend = value
|
137
149
|
if self._updating_info:
|
138
150
|
return
|
151
|
+
self.__ensure_pk()
|
139
152
|
assert self.contact_pk is not None
|
140
153
|
self.xmpp.store.contacts.set_friend(self.contact_pk, value)
|
141
154
|
|
@@ -157,7 +170,10 @@ class LegacyContact(
|
|
157
170
|
|
158
171
|
@property
|
159
172
|
def participants(self) -> list["LegacyParticipant"]:
|
160
|
-
|
173
|
+
if self.contact_pk is None:
|
174
|
+
return []
|
175
|
+
|
176
|
+
self.__ensure_pk()
|
161
177
|
from ..group.participant import LegacyParticipant
|
162
178
|
|
163
179
|
return [
|
@@ -171,8 +187,25 @@ class LegacyContact(
|
|
171
187
|
def user_jid(self):
|
172
188
|
return self.session.user_jid
|
173
189
|
|
190
|
+
def _set_logger_name(self):
|
191
|
+
self.log.name = f"{self.user_jid.bare}:contact:{self}"
|
192
|
+
|
174
193
|
def __repr__(self):
|
175
|
-
return f"<Contact {self.
|
194
|
+
return f"<Contact #{self.contact_pk} '{self.name}' ({self.legacy_id} - {self.jid.local})'>"
|
195
|
+
|
196
|
+
def __ensure_pk(self):
|
197
|
+
if self.contact_pk is not None:
|
198
|
+
return
|
199
|
+
with self.xmpp.store.session() as orm:
|
200
|
+
orm.commit()
|
201
|
+
stored = self.xmpp.store.contacts.get_by_legacy_id(
|
202
|
+
self.user_pk, str(self.legacy_id)
|
203
|
+
)
|
204
|
+
if stored is None:
|
205
|
+
self.log.error("Cannot find our primary key!", stack_info=True)
|
206
|
+
raise RuntimeError("Cannot find our primary key!")
|
207
|
+
self.contact_pk = stored.id
|
208
|
+
assert self.contact_pk is not None
|
176
209
|
|
177
210
|
def __get_subscription_string(self):
|
178
211
|
if self.is_friend:
|
@@ -234,6 +267,7 @@ class LegacyContact(
|
|
234
267
|
and self.xmpp.MARK_ALL_MESSAGES
|
235
268
|
and is_markable(stanza)
|
236
269
|
):
|
270
|
+
self.__ensure_pk()
|
237
271
|
assert self.contact_pk is not None
|
238
272
|
self.xmpp.store.contacts.add_to_sent(self.contact_pk, stanza["id"])
|
239
273
|
stanza["to"] = self.user_jid
|
@@ -254,6 +288,7 @@ class LegacyContact(
|
|
254
288
|
:param horizon_xmpp_id: The latest message
|
255
289
|
:return: A list of XMPP ids or None if horizon_xmpp_id was not found
|
256
290
|
"""
|
291
|
+
self.__ensure_pk()
|
257
292
|
assert self.contact_pk is not None
|
258
293
|
return self.xmpp.store.contacts.pop_sent_up_to(self.contact_pk, horizon_xmpp_id)
|
259
294
|
|
@@ -269,6 +304,7 @@ class LegacyContact(
|
|
269
304
|
if self._name == n:
|
270
305
|
return
|
271
306
|
self._name = n
|
307
|
+
self._set_logger_name()
|
272
308
|
if self.is_friend and self.added_to_roster:
|
273
309
|
self.xmpp.pubsub.broadcast_nick(
|
274
310
|
user_jid=self.user_jid, jid=self.jid.bare, nick=n
|
@@ -279,6 +315,7 @@ class LegacyContact(
|
|
279
315
|
return
|
280
316
|
for p in self.participants:
|
281
317
|
p.nickname = n
|
318
|
+
self.__ensure_pk()
|
282
319
|
assert self.contact_pk is not None
|
283
320
|
self.xmpp.store.contacts.update_nick(self.contact_pk, n)
|
284
321
|
|
@@ -293,6 +330,7 @@ class LegacyContact(
|
|
293
330
|
if self.contact_pk is None:
|
294
331
|
# happens in LegacyRoster.fill(), the contact primary key is not
|
295
332
|
# set yet, but this will eventually be called in LegacyRoster.__finish_init_contact
|
333
|
+
self.log.debug("Not setting avatar PK")
|
296
334
|
return
|
297
335
|
self.xmpp.store.contacts.set_avatar(self.contact_pk, self._avatar_pk)
|
298
336
|
for p in self.participants:
|
@@ -346,7 +384,17 @@ class LegacyContact(
|
|
346
384
|
elif country:
|
347
385
|
vcard.add_address(country, locality)
|
348
386
|
|
349
|
-
self.
|
387
|
+
self._vcard = str(vcard)
|
388
|
+
self._vcard_fetched = True
|
389
|
+
self.session.create_task(
|
390
|
+
self.xmpp.pubsub.broadcast_vcard_event(self.jid, self.user_jid, vcard)
|
391
|
+
)
|
392
|
+
|
393
|
+
if self._updating_info:
|
394
|
+
return
|
395
|
+
|
396
|
+
assert self.contact_pk is not None
|
397
|
+
self.xmpp.store.contacts.set_vcard(self.contact_pk, self._vcard)
|
350
398
|
|
351
399
|
def get_roster_item(self):
|
352
400
|
item = {
|
@@ -430,7 +478,7 @@ class LegacyContact(
|
|
430
478
|
"""
|
431
479
|
self.is_friend = True
|
432
480
|
self.added_to_roster = True
|
433
|
-
|
481
|
+
self.__ensure_pk()
|
434
482
|
self.log.debug("Accepting friend request")
|
435
483
|
presence = self._make_presence(ptype="subscribed", pstatus=text, bare=True)
|
436
484
|
self._send(presence, nick=True)
|
@@ -554,8 +602,11 @@ class LegacyContact(
|
|
554
602
|
contact.added_to_roster = stored.added_to_roster
|
555
603
|
if (data := stored.extra_attributes) is not None:
|
556
604
|
contact.deserialize_extra_attributes(data)
|
557
|
-
contact._set_avatar_from_store(stored)
|
558
605
|
contact._caps_ver = stored.caps_ver
|
606
|
+
contact._set_logger_name()
|
607
|
+
contact._set_avatar_from_store(stored)
|
608
|
+
contact._vcard = stored.vcard
|
609
|
+
contact._vcard_fetched = stored.vcard_fetched
|
559
610
|
return contact
|
560
611
|
|
561
612
|
|
slidge/core/gateway/base.py
CHANGED
@@ -36,7 +36,6 @@ from ...command.register import RegistrationType
|
|
36
36
|
from ...db import GatewayUser, SlidgeStore
|
37
37
|
from ...db.avatar import avatar_cache
|
38
38
|
from ...slixfix.roster import RosterBackend
|
39
|
-
from ...slixfix.xep_0292.vcard4 import VCard4Provider
|
40
39
|
from ...util import ABCSubclassableOnceAtMost
|
41
40
|
from ...util.types import AvatarType, MessageOrPresenceTypeVar
|
42
41
|
from ...util.util import timeit
|
@@ -331,7 +330,6 @@ class BaseGateway(
|
|
331
330
|
|
332
331
|
self.register_plugin("pubsub", {"component_name": self.COMPONENT_NAME})
|
333
332
|
self.pubsub: PubSubComponent = self["pubsub"]
|
334
|
-
self.vcard: VCard4Provider = self["xep_0292_provider"]
|
335
333
|
self.delivery_receipt: DeliveryReceipt = DeliveryReceipt(self)
|
336
334
|
|
337
335
|
# with this we receive user avatar updates
|
@@ -68,6 +68,13 @@ class SessionDispatcher:
|
|
68
68
|
_exceptions_to_xmpp_errors(self.on_ibr_remove), # type: ignore
|
69
69
|
)
|
70
70
|
)
|
71
|
+
self.xmpp.register_handler(
|
72
|
+
CoroutineCallback(
|
73
|
+
"get_vcard",
|
74
|
+
StanzaPath("iq@type=get/vcard"),
|
75
|
+
_exceptions_to_xmpp_errors(self.on_get_vcard), # type:ignore
|
76
|
+
)
|
77
|
+
)
|
71
78
|
|
72
79
|
for event in (
|
73
80
|
"legacy_message",
|
@@ -778,6 +785,18 @@ class SessionDispatcher:
|
|
778
785
|
|
779
786
|
raise XMPPError("feature-not-implemented")
|
780
787
|
|
788
|
+
async def on_get_vcard(self, iq: Iq):
|
789
|
+
session = await self.__get_session(iq)
|
790
|
+
session.raise_if_not_logged()
|
791
|
+
contact = await session.contacts.by_jid(iq.get_to())
|
792
|
+
vcard = await contact.get_vcard()
|
793
|
+
reply = iq.reply()
|
794
|
+
if vcard:
|
795
|
+
reply.append(vcard)
|
796
|
+
else:
|
797
|
+
reply.enable("vcard")
|
798
|
+
reply.send()
|
799
|
+
|
781
800
|
def _xmpp_msg_id_to_legacy(self, session: "BaseSession", xmpp_id: str):
|
782
801
|
sent = self.xmpp.store.sent.get_legacy_id(session.user_pk, xmpp_id)
|
783
802
|
if sent is not None:
|
@@ -79,14 +79,14 @@ class VCardTemp:
|
|
79
79
|
elif not (contact := entity.contact):
|
80
80
|
raise XMPPError("item-not-found", "This participant has no contact")
|
81
81
|
else:
|
82
|
-
vcard = await
|
82
|
+
vcard = await contact.get_vcard()
|
83
83
|
avatar = contact.get_avatar()
|
84
84
|
type_ = "image/png"
|
85
85
|
else:
|
86
86
|
avatar = entity.get_avatar()
|
87
87
|
type_ = "image/png"
|
88
88
|
if isinstance(entity, LegacyContact):
|
89
|
-
vcard = await
|
89
|
+
vcard = await entity.get_vcard()
|
90
90
|
else:
|
91
91
|
vcard = None
|
92
92
|
v = self.xmpp.plugin["xep_0054"].make_vcard()
|
slidge/core/pubsub.py
CHANGED
@@ -135,6 +135,7 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
|
|
135
135
|
|
136
136
|
to = p.get_to()
|
137
137
|
|
138
|
+
contact = None
|
138
139
|
# we don't want to push anything for contacts that are not in the user's roster
|
139
140
|
if to != self.xmpp.boundjid.bare:
|
140
141
|
session = self.xmpp.get_session_from_stanza(p)
|
@@ -186,17 +187,19 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
|
|
186
187
|
else:
|
187
188
|
await self.__broadcast(data=pep_nick.nick, from_=p.get_to(), to=from_)
|
188
189
|
|
189
|
-
if VCARD4_NAMESPACE + "+notify" in features:
|
190
|
-
await self.broadcast_vcard_event(
|
190
|
+
if contact is not None and VCARD4_NAMESPACE + "+notify" in features:
|
191
|
+
await self.broadcast_vcard_event(
|
192
|
+
p.get_to(), from_, await contact.get_vcard()
|
193
|
+
)
|
191
194
|
|
192
|
-
async def broadcast_vcard_event(self, from_, to):
|
195
|
+
async def broadcast_vcard_event(self, from_: JID, to: JID, vcard: VCard4 | None):
|
193
196
|
item = Item()
|
194
197
|
item.namespace = VCARD4_NAMESPACE
|
195
198
|
item["id"] = "current"
|
196
|
-
vcard: VCard4 = await self.xmpp["xep_0292_provider"].get_vcard(from_, to)
|
199
|
+
# vcard: VCard4 = await self.xmpp["xep_0292_provider"].get_vcard(from_, to)
|
197
200
|
# The vcard content should NOT be in this event according to the spec:
|
198
201
|
# https://xmpp.org/extensions/xep-0292.html#sect-idm45669698174224
|
199
|
-
# but movim expects it to be here, and I guess
|
202
|
+
# but movim expects it to be here, and I guess it does not hurt
|
200
203
|
|
201
204
|
log.debug("Broadcast vcard4 event: %s", vcard)
|
202
205
|
await self.__broadcast(
|
@@ -268,10 +271,9 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
|
|
268
271
|
# this is not the proper way that clients should retrieve VCards, but
|
269
272
|
# gajim does it this way.
|
270
273
|
# https://xmpp.org/extensions/xep-0292.html#sect-idm45669698174224
|
271
|
-
|
272
|
-
|
273
|
-
)
|
274
|
-
log.debug("VCARD: %s -- %s -- %s", iq.get_to().bare, iq.get_from().bare, vcard)
|
274
|
+
session = self.xmpp.get_session_from_stanza(iq)
|
275
|
+
contact = await session.contacts.by_jid(iq.get_to())
|
276
|
+
vcard = await contact.get_vcard()
|
275
277
|
if vcard is None:
|
276
278
|
raise XMPPError("item-not-found")
|
277
279
|
self._reply_with_payload(iq, vcard, "current", VCARD4_NAMESPACE)
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
"""Lift room legacy ID constraint
|
2
|
+
|
3
|
+
Revision ID: 5bd48bfdffa2
|
4
|
+
Revises: b64b1a793483
|
5
|
+
Create Date: 2024-07-24 10:29:23.467851
|
6
|
+
|
7
|
+
"""
|
8
|
+
|
9
|
+
from typing import Sequence, Union
|
10
|
+
|
11
|
+
from alembic import op
|
12
|
+
|
13
|
+
from slidge.db.models import Room
|
14
|
+
|
15
|
+
# revision identifiers, used by Alembic.
|
16
|
+
revision: str = "5bd48bfdffa2"
|
17
|
+
down_revision: Union[str, None] = "b64b1a793483"
|
18
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
19
|
+
depends_on: Union[str, Sequence[str], None] = None
|
20
|
+
|
21
|
+
|
22
|
+
def upgrade() -> None:
|
23
|
+
with op.batch_alter_table(
|
24
|
+
"room",
|
25
|
+
schema=None,
|
26
|
+
# without copy_from, the newly created table keeps the constraints
|
27
|
+
# we actually want to ditch.
|
28
|
+
copy_from=Room.__table__, # type:ignore
|
29
|
+
) as batch_op:
|
30
|
+
batch_op.create_unique_constraint(
|
31
|
+
"uq_room_user_account_id_jid", ["user_account_id", "jid"]
|
32
|
+
)
|
33
|
+
batch_op.create_unique_constraint(
|
34
|
+
"uq_room_user_account_id_legacy_id", ["user_account_id", "legacy_id"]
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
def downgrade() -> None:
|
39
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
40
|
+
with op.batch_alter_table("room", schema=None) as batch_op:
|
41
|
+
batch_op.drop_constraint("uq_room_user_account_id_legacy_id", type_="unique")
|
42
|
+
batch_op.drop_constraint("uq_room_user_account_id_jid", type_="unique")
|
43
|
+
|
44
|
+
# ### end Alembic commands ###
|
@@ -0,0 +1,43 @@
|
|
1
|
+
"""Add vcard content to contact table
|
2
|
+
|
3
|
+
Revision ID: 8b993243a536
|
4
|
+
Revises: 5bd48bfdffa2
|
5
|
+
Create Date: 2024-07-24 07:02:47.770894
|
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 = "8b993243a536"
|
16
|
+
down_revision: Union[str, None] = "5bd48bfdffa2"
|
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
|
+
with op.batch_alter_table("contact", schema=None) as batch_op:
|
24
|
+
batch_op.add_column(sa.Column("vcard", sa.String(), nullable=True))
|
25
|
+
batch_op.add_column(
|
26
|
+
sa.Column(
|
27
|
+
"vcard_fetched",
|
28
|
+
sa.Boolean(),
|
29
|
+
nullable=False,
|
30
|
+
server_default=sa.sql.true(),
|
31
|
+
)
|
32
|
+
)
|
33
|
+
|
34
|
+
# ### end Alembic commands ###
|
35
|
+
|
36
|
+
|
37
|
+
def downgrade() -> None:
|
38
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
39
|
+
with op.batch_alter_table("contact", schema=None) as batch_op:
|
40
|
+
batch_op.drop_column("vcard_fetched")
|
41
|
+
batch_op.drop_column("vcard")
|
42
|
+
|
43
|
+
# ### end Alembic commands ###
|
@@ -58,10 +58,19 @@ def downgrade() -> None:
|
|
58
58
|
|
59
59
|
|
60
60
|
def migrate_from_shelf(accounts: sa.Table) -> None:
|
61
|
+
from slidge import global_config
|
62
|
+
|
63
|
+
db_file = global_config.HOME_DIR / "slidge.db"
|
64
|
+
if not db_file.exists():
|
65
|
+
return
|
66
|
+
|
61
67
|
try:
|
62
|
-
from slidge.
|
68
|
+
from slidge.db.alembic.old_user_store import user_store
|
63
69
|
except ImportError:
|
64
70
|
return
|
71
|
+
|
72
|
+
user_store.set_file(db_file, global_config.SECRET_KEY)
|
73
|
+
|
65
74
|
try:
|
66
75
|
users = list(user_store.get_all())
|
67
76
|
except AttributeError:
|
@@ -83,3 +92,6 @@ def migrate_from_shelf(accounts: sa.Table) -> None:
|
|
83
92
|
for user in users
|
84
93
|
],
|
85
94
|
)
|
95
|
+
|
96
|
+
user_store.close()
|
97
|
+
db_file.unlink()
|
slidge/db/meta.py
CHANGED
@@ -58,6 +58,13 @@ JSONSerializable = dict[str, JSONSerializableTypes]
|
|
58
58
|
|
59
59
|
class Base(sa.orm.DeclarativeBase):
|
60
60
|
type_annotation_map = {JSONSerializable: JSONEncodedDict, JID: JIDType}
|
61
|
+
naming_convention = {
|
62
|
+
"ix": "ix_%(column_0_label)s",
|
63
|
+
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
64
|
+
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
|
65
|
+
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
66
|
+
"pk": "pk_%(table_name)s",
|
67
|
+
}
|
61
68
|
|
62
69
|
|
63
70
|
def get_engine(path: str) -> sa.Engine:
|
slidge/db/models.py
CHANGED
@@ -166,6 +166,9 @@ class Contact(Base):
|
|
166
166
|
)
|
167
167
|
updated: Mapped[bool] = mapped_column(default=False)
|
168
168
|
|
169
|
+
vcard: Mapped[Optional[str]] = mapped_column()
|
170
|
+
vcard_fetched: Mapped[bool] = mapped_column(default=False)
|
171
|
+
|
169
172
|
participants: Mapped[list["Participant"]] = relationship(back_populates="contact")
|
170
173
|
|
171
174
|
|
@@ -191,13 +194,20 @@ class Room(Base):
|
|
191
194
|
Legacy room
|
192
195
|
"""
|
193
196
|
|
197
|
+
__table_args__ = (
|
198
|
+
UniqueConstraint(
|
199
|
+
"user_account_id", "legacy_id", name="uq_room_user_account_id_legacy_id"
|
200
|
+
),
|
201
|
+
UniqueConstraint("user_account_id", "jid", name="uq_room_user_account_id_jid"),
|
202
|
+
)
|
203
|
+
|
194
204
|
__tablename__ = "room"
|
195
205
|
id: Mapped[int] = mapped_column(primary_key=True)
|
196
206
|
user_account_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
|
197
207
|
user: Mapped[GatewayUser] = relationship(back_populates="rooms")
|
198
|
-
legacy_id: Mapped[str] = mapped_column(
|
208
|
+
legacy_id: Mapped[str] = mapped_column(nullable=False)
|
199
209
|
|
200
|
-
jid: Mapped[JID] = mapped_column(
|
210
|
+
jid: Mapped[JID] = mapped_column(nullable=False)
|
201
211
|
|
202
212
|
avatar_id: Mapped[int] = mapped_column(ForeignKey("avatar.id"), nullable=True)
|
203
213
|
avatar: Mapped[Avatar] = relationship(back_populates="rooms")
|
slidge/db/store.py
CHANGED
@@ -32,6 +32,7 @@ from .models import (
|
|
32
32
|
XmppIdsMulti,
|
33
33
|
XmppToLegacyEnum,
|
34
34
|
XmppToLegacyIds,
|
35
|
+
participant_hats,
|
35
36
|
)
|
36
37
|
|
37
38
|
if TYPE_CHECKING:
|
@@ -379,11 +380,22 @@ class ContactStore(UpdatedMixin):
|
|
379
380
|
row.updated = True
|
380
381
|
row.extra_attributes = contact.serialize_extra_attributes()
|
381
382
|
row.caps_ver = contact._caps_ver
|
383
|
+
row.vcard = contact._vcard
|
384
|
+
row.vcard_fetched = contact._vcard_fetched
|
382
385
|
session.add(row)
|
383
386
|
if commit:
|
384
387
|
session.commit()
|
385
388
|
return row.id
|
386
389
|
|
390
|
+
def set_vcard(self, contact_pk: int, vcard: str | None) -> None:
|
391
|
+
with self.session() as session:
|
392
|
+
session.execute(
|
393
|
+
update(Contact)
|
394
|
+
.where(Contact.id == contact_pk)
|
395
|
+
.values(vcard=vcard, vcard_fetched=True)
|
396
|
+
)
|
397
|
+
session.commit()
|
398
|
+
|
387
399
|
def add_to_sent(self, contact_pk: int, msg_id: str) -> None:
|
388
400
|
with self.session() as session:
|
389
401
|
new = ContactSent(contact_id=contact_pk, msg_id=msg_id)
|
@@ -659,7 +671,7 @@ class MultiStore(EngineMixin):
|
|
659
671
|
if existing is not None:
|
660
672
|
if fail:
|
661
673
|
raise
|
662
|
-
log.
|
674
|
+
log.debug("Resetting multi for %s", legacy_msg_id)
|
663
675
|
session.execute(
|
664
676
|
delete(LegacyIdsMulti)
|
665
677
|
.where(LegacyIdsMulti.user_account_id == user_pk)
|
@@ -935,6 +947,7 @@ class ParticipantStore(EngineMixin):
|
|
935
947
|
with self.session() as session:
|
936
948
|
session.execute(delete(Participant))
|
937
949
|
session.execute(delete(Hat))
|
950
|
+
session.execute(delete(participant_hats))
|
938
951
|
session.commit()
|
939
952
|
|
940
953
|
def add(self, room_pk: int, nickname: str) -> int:
|
slidge/group/room.py
CHANGED
@@ -131,7 +131,6 @@ class LegacyMUC(
|
|
131
131
|
def __init__(self, session: "BaseSession", legacy_id: LegacyGroupIdType, jid: JID):
|
132
132
|
self.session = session
|
133
133
|
self.xmpp: "BaseGateway" = session.xmpp
|
134
|
-
self.log = logging.getLogger(f"{self.user_jid.bare}:muc:{jid}")
|
135
134
|
|
136
135
|
self.legacy_id = legacy_id
|
137
136
|
self.jid = jid
|
@@ -156,6 +155,8 @@ class LegacyMUC(
|
|
156
155
|
|
157
156
|
self._n_participants: Optional[int] = None
|
158
157
|
|
158
|
+
self.log = logging.getLogger(self.jid.bare)
|
159
|
+
self._set_logger_name()
|
159
160
|
super().__init__()
|
160
161
|
|
161
162
|
@property
|
@@ -176,8 +177,11 @@ class LegacyMUC(
|
|
176
177
|
def user_jid(self):
|
177
178
|
return self.session.user_jid
|
178
179
|
|
180
|
+
def _set_logger_name(self):
|
181
|
+
self.log = logging.getLogger(f"{self.user_jid}:muc:{self}")
|
182
|
+
|
179
183
|
def __repr__(self):
|
180
|
-
return f"<MUC {self.
|
184
|
+
return f"<MUC #{self.pk} '{self.name}' ({self.legacy_id} - {self.jid.local})'>"
|
181
185
|
|
182
186
|
@property
|
183
187
|
def subject_date(self) -> Optional[datetime]:
|
@@ -287,6 +291,7 @@ class LegacyMUC(
|
|
287
291
|
if self.DISCO_NAME == n:
|
288
292
|
return
|
289
293
|
self.DISCO_NAME = n
|
294
|
+
self._set_logger_name()
|
290
295
|
self.__send_configuration_change((104,))
|
291
296
|
if self._updating_info:
|
292
297
|
return
|
@@ -1207,6 +1212,7 @@ class LegacyMUC(
|
|
1207
1212
|
muc._user_resources = set(json.loads(stored.user_resources))
|
1208
1213
|
muc._subject_setter = stored.subject_setter
|
1209
1214
|
muc.archive = MessageArchive(muc.pk, session.xmpp.store.mam)
|
1215
|
+
muc._set_logger_name()
|
1210
1216
|
muc._set_avatar_from_store(stored)
|
1211
1217
|
return muc
|
1212
1218
|
|
slidge/main.py
CHANGED
@@ -32,7 +32,6 @@ from slidge.db.avatar import avatar_cache
|
|
32
32
|
from slidge.db.meta import get_engine
|
33
33
|
from slidge.migration import migrate
|
34
34
|
from slidge.util.conf import ConfigModule
|
35
|
-
from slidge.util.db import user_store
|
36
35
|
|
37
36
|
|
38
37
|
class MainConfig(ConfigModule):
|
@@ -114,9 +113,6 @@ def configure():
|
|
114
113
|
logging.info("Creating directory '%s'", h)
|
115
114
|
h.mkdir()
|
116
115
|
|
117
|
-
db_file = config.HOME_DIR / "slidge.db"
|
118
|
-
user_store.set_file(db_file, args.secret_key)
|
119
|
-
|
120
116
|
config.UPLOAD_REQUESTER = config.UPLOAD_REQUESTER or config.JID.bare
|
121
117
|
|
122
118
|
return unknown_argv
|
slidge/slixfix/roster.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
+
import logging
|
1
2
|
from typing import TYPE_CHECKING
|
2
3
|
|
3
4
|
from slixmpp import JID
|
4
5
|
|
5
|
-
from ..util.db import log
|
6
|
-
|
7
6
|
if TYPE_CHECKING:
|
8
7
|
from .. import BaseGateway
|
9
8
|
|
@@ -65,3 +64,6 @@ class RosterBackend:
|
|
65
64
|
"whitelisted": False,
|
66
65
|
"subscription": "none",
|
67
66
|
}
|
67
|
+
|
68
|
+
|
69
|
+
log = logging.getLogger(__name__)
|
@@ -1,103 +1,14 @@
|
|
1
|
-
import logging
|
2
|
-
from typing import TYPE_CHECKING, NamedTuple, Optional
|
3
|
-
|
4
|
-
from slixmpp import JID, CoroutineCallback, Iq, StanzaPath
|
5
1
|
from slixmpp.plugins.base import BasePlugin, register_plugin
|
6
|
-
from slixmpp.plugins.xep_0292.stanza import NS
|
7
|
-
from slixmpp.types import JidStr
|
8
|
-
|
9
|
-
from slidge.contact import LegacyContact
|
10
|
-
|
11
|
-
if TYPE_CHECKING:
|
12
|
-
from slidge.core.gateway import BaseGateway
|
13
|
-
|
14
|
-
|
15
|
-
class StoredVCard(NamedTuple):
|
16
|
-
content: VCard4
|
17
|
-
authorized_jids: set[JidStr]
|
2
|
+
from slixmpp.plugins.xep_0292.stanza import NS
|
18
3
|
|
19
4
|
|
20
5
|
class VCard4Provider(BasePlugin):
|
21
|
-
xmpp: "BaseGateway"
|
22
|
-
|
23
6
|
name = "xep_0292_provider"
|
24
7
|
description = "VCard4 Provider"
|
25
8
|
dependencies = {"xep_0030"}
|
26
9
|
|
27
|
-
def __init__(self, *a, **k):
|
28
|
-
super(VCard4Provider, self).__init__(*a, **k)
|
29
|
-
# TODO: store that in DB and not in RAM
|
30
|
-
self._vcards = dict[JidStr, StoredVCard]()
|
31
|
-
|
32
10
|
def plugin_init(self):
|
33
|
-
self.xmpp.register_handler(
|
34
|
-
CoroutineCallback(
|
35
|
-
"get_vcard",
|
36
|
-
StanzaPath(f"iq@type=get/vcard"),
|
37
|
-
self.handle_vcard_get, # type:ignore
|
38
|
-
)
|
39
|
-
)
|
40
|
-
|
41
11
|
self.xmpp.plugin["xep_0030"].add_feature(NS)
|
42
12
|
|
43
|
-
def _get_cached_vcard(self, jid: JidStr, requested_by: JidStr) -> Optional[VCard4]:
|
44
|
-
vcard = self._vcards.get(JID(jid).bare)
|
45
|
-
if vcard:
|
46
|
-
if auth := vcard.authorized_jids:
|
47
|
-
if JID(requested_by).bare in auth:
|
48
|
-
return vcard.content
|
49
|
-
else:
|
50
|
-
return vcard.content
|
51
|
-
return None
|
52
|
-
|
53
|
-
async def get_vcard(self, jid: JidStr, requested_by: JidStr) -> Optional[VCard4]:
|
54
|
-
if vcard := self._get_cached_vcard(jid, requested_by):
|
55
|
-
log.debug("Found a cached vcard")
|
56
|
-
return vcard
|
57
|
-
if not hasattr(self.xmpp, "get_session_from_jid"):
|
58
|
-
return None
|
59
|
-
jid = JID(jid)
|
60
|
-
if not jid.local:
|
61
|
-
return None
|
62
|
-
requested_by = JID(requested_by)
|
63
|
-
session = self.xmpp.get_session_from_jid(requested_by)
|
64
|
-
if session is None:
|
65
|
-
return
|
66
|
-
entity = await session.get_contact_or_group_or_participant(jid)
|
67
|
-
if isinstance(entity, LegacyContact):
|
68
|
-
log.debug("Fetching vcard")
|
69
|
-
await entity.fetch_vcard()
|
70
|
-
return self._get_cached_vcard(jid, requested_by)
|
71
|
-
return None
|
72
|
-
|
73
|
-
async def handle_vcard_get(self, iq: Iq):
|
74
|
-
r = iq.reply()
|
75
|
-
if vcard := await self.get_vcard(iq.get_to().bare, iq.get_from().bare):
|
76
|
-
r.append(vcard)
|
77
|
-
else:
|
78
|
-
r.enable("vcard")
|
79
|
-
r.send()
|
80
|
-
|
81
|
-
def set_vcard(
|
82
|
-
self,
|
83
|
-
jid: JidStr,
|
84
|
-
vcard: VCard4,
|
85
|
-
/,
|
86
|
-
authorized_jids: Optional[set[JidStr]] = None,
|
87
|
-
):
|
88
|
-
cache = self._vcards.get(jid)
|
89
|
-
new = StoredVCard(
|
90
|
-
vcard, authorized_jids if authorized_jids is not None else set()
|
91
|
-
)
|
92
|
-
self._vcards[jid] = new
|
93
|
-
if cache == new:
|
94
|
-
return
|
95
|
-
if self.xmpp["pubsub"] and authorized_jids:
|
96
|
-
for to in authorized_jids:
|
97
|
-
self.xmpp.loop.create_task(
|
98
|
-
self.xmpp["pubsub"].broadcast_vcard_event(jid, to)
|
99
|
-
)
|
100
|
-
|
101
13
|
|
102
14
|
register_plugin(VCard4Provider)
|
103
|
-
log = logging.getLogger(__name__)
|
slidge/util/test.py
CHANGED
@@ -287,7 +287,7 @@ class SlidgeTest(SlixTestPlus):
|
|
287
287
|
stanza = self.next_sent()
|
288
288
|
assert "yup" in stanza["status"].lower(), stanza
|
289
289
|
|
290
|
-
self.romeo = BaseSession.get_self_or_unique_subclass().from_jid(
|
290
|
+
self.romeo: BaseSession = BaseSession.get_self_or_unique_subclass().from_jid(
|
291
291
|
JID("romeo@montague.lit")
|
292
292
|
)
|
293
293
|
self.juliet: LegacyContact = self.run_coro(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
slidge/__init__.py,sha256=S0tUjqpZlzsr8G4Y_1Xt-KCYB07qaknTB0OwHU8k29U,1587
|
2
2
|
slidge/__main__.py,sha256=Y12eh1TD_C5MB50KgEAuMffGnRFCvKYFKHD4UYSmHA0,72
|
3
|
-
slidge/__version__.py,sha256=
|
3
|
+
slidge/__version__.py,sha256=Ip83rsG7PNyMNP7tUYp3yfTqTCEX_G49W_HLxj1iJ7U,170
|
4
4
|
slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
|
5
5
|
slidge/command/adhoc.py,sha256=5xLLoWyUJqCJB7kAwD2VKYTl_7MObCsgdz-qg_WkWGs,9417
|
6
6
|
slidge/command/admin.py,sha256=JAN8s-b2KckgUozAQNBGOzkrEaQv-LtwezYgOsAR6Ng,5768
|
@@ -10,12 +10,12 @@ slidge/command/chat_command.py,sha256=kMnxrzmD7LhWgyO1w9Rgz1eA7PhfAJ2Rf34YWjoKrw
|
|
10
10
|
slidge/command/register.py,sha256=fzPcGUoJtainnDOiC13gWV-uYLuJcsmdKGJ-jXT1qIo,6697
|
11
11
|
slidge/command/user.py,sha256=nJnoU4t1r9oPkFFHSHHwSY8WOQNLQn9mMcwZp-yZaKA,11422
|
12
12
|
slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
|
13
|
-
slidge/contact/contact.py,sha256=
|
13
|
+
slidge/contact/contact.py,sha256=l0zolnfrcSdS7z49TI-CSzjQiqJ-ARSMnZuszBcILXk,21894
|
14
14
|
slidge/contact/roster.py,sha256=2EGV7q0km6JEahn2brr-td0KJILtXQGFWiSPuORA86I,10756
|
15
15
|
slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
|
16
16
|
slidge/core/config.py,sha256=leNcN_TI0Ka1hhzOHx7cBW3fNj5xZwsiv9l8AfRY_vU,7630
|
17
17
|
slidge/core/gateway/__init__.py,sha256=rZckY2gAE-mon77_DSsAW1XtWqhBAETE2d4FqZ8pJXk,58
|
18
|
-
slidge/core/gateway/base.py,sha256=
|
18
|
+
slidge/core/gateway/base.py,sha256=6AOWuJPC4GkLcsgvrxHT5Y86g2x6Kv0iMbkp2wjepxo,38483
|
19
19
|
slidge/core/gateway/caps.py,sha256=jemB4tB_2MTAxqQw5Bs4b7qNQ8gLPuAve0aoH6TzLEs,1937
|
20
20
|
slidge/core/gateway/delivery_receipt.py,sha256=AT_9gvZrtWpSRsDJcYjE8CmF7TW-YBbUPdqNW5zWAdo,1352
|
21
21
|
slidge/core/gateway/disco.py,sha256=uazgDXSDb5KrardjPCvElItARcxkeBRohtx82A2BlCQ,2203
|
@@ -25,8 +25,8 @@ slidge/core/gateway/ping.py,sha256=_zzPkjqvxjTxLNP1jbj0WVLMaybxbYqrKDRM5jHSDjs,1
|
|
25
25
|
slidge/core/gateway/presence.py,sha256=Ls8IY4uNQaW8F3F1CpRhfyFIVbd_py_VkZyJKMMei8s,2732
|
26
26
|
slidge/core/gateway/registration.py,sha256=JXwIQ-QqZCPXEmCU2G8FvIYDGvD8L8CqGb_Qkbycgt0,2303
|
27
27
|
slidge/core/gateway/search.py,sha256=08ds6gvzX3EnTH-AU8X8J8JKEKYaSrRGTFwwClTT-Rc,3495
|
28
|
-
slidge/core/gateway/session_dispatcher.py,sha256=
|
29
|
-
slidge/core/gateway/vcard_temp.py,sha256=
|
28
|
+
slidge/core/gateway/session_dispatcher.py,sha256=F8YGUCB7hA1PNsGgQDaUYHmLnf4e8NWptIh-9ra_43c,32930
|
29
|
+
slidge/core/gateway/vcard_temp.py,sha256=2FeP-comBg8A-OtB-II1jlxyDib_C4R8vfnJHGNkzyc,4626
|
30
30
|
slidge/core/mixins/__init__.py,sha256=muReAzgvENgMvlfm0Fpe6BQFfm2EMjoDe9ZhGgo6Vig,627
|
31
31
|
slidge/core/mixins/attachment.py,sha256=YXuObz68eem2AND1q-RBeZ-X9Zi_IlUgx0DRMiwM3Xw,18706
|
32
32
|
slidge/core/mixins/avatar.py,sha256=ke3cwm6Iiz1AM0_SiARTUTU2nGYskPZlxtFrXKQT5fI,7812
|
@@ -38,39 +38,43 @@ slidge/core/mixins/message.py,sha256=jJz_peNQmDf0uVQcI7TWG7oUaSGjUL8eiulNicGgWhI
|
|
38
38
|
slidge/core/mixins/message_maker.py,sha256=TcCutHi0sIwL6beJNkN7XyR0aDIbA0xZyxd2Gc9ulG4,6022
|
39
39
|
slidge/core/mixins/presence.py,sha256=yywo6KAw8C7GaZSMrSMuioNfhW08MrnobHt8XbHd0q8,7891
|
40
40
|
slidge/core/mixins/recipient.py,sha256=U-YppozUO8pA94jmD3-qmhkykTebPNaOVWc3JDPC9w8,1302
|
41
|
-
slidge/core/pubsub.py,sha256=
|
41
|
+
slidge/core/pubsub.py,sha256=ofiZEw0tgckpdJJW102fj7MovUXBrCHYufaHaad4oFo,12390
|
42
42
|
slidge/core/session.py,sha256=IUZur7huNj066uy-Nh-I-R0etYmPJccgXFIimcSQ148,27161
|
43
43
|
slidge/db/__init__.py,sha256=EBDH1JSEhgqYcli2Bw11CRC749wJk8AOucgBzmhDSvU,105
|
44
|
+
slidge/db/alembic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
45
|
slidge/db/alembic/env.py,sha256=hsBlRNs0zF5diSHGRSa8Fi3qRVQDA2rJdR41AEIdvxc,1642
|
46
|
+
slidge/db/alembic/old_user_store.py,sha256=zFOv0JEWQQK0_TMRlU4Z0G5Mc9pxvEErLyOzXmRAe5Q,5209
|
45
47
|
slidge/db/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
46
48
|
slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py,sha256=mUL-0Io6ZPd_QbnKfwGYyjdMcM2uxQ0Wg72H23-2t_E,1033
|
47
49
|
slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py,sha256=CLB-kOP9Rc0FJIKDLef912L5sYkjpTIPC8fhrIdrC7k,1084
|
48
50
|
slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py,sha256=f8TFS28CXjGhvIn41UYMoHYeODfqhKfo4O7gk-JwA1E,1134
|
49
51
|
slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py,sha256=CMVP2wFz6s7t57eWdSaGtck8BXzfVPJhHE5AoWi34tI,1359
|
52
|
+
slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py,sha256=wk958rfBuop9mw6wI_dDQUeTdiCCV6GJb-WcP4h1xVs,1340
|
50
53
|
slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py,sha256=g37po0ydp8ZmzJrE5oFV7GscnploxjCtPDpw28SqVGk,1429
|
54
|
+
slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py,sha256=18tG8B03Kq8Qz_-mMd28Beed6jow8XNTtrz7gT5QY3g,1210
|
51
55
|
slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py,sha256=olXaOEEsUSasqaaKdlP1cBODsMhmV1i90qbpDM2vTm4,4696
|
52
|
-
slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py,sha256=
|
56
|
+
slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py,sha256=XOf6Oiot2wLsngvUwrM30LbuVNm549FWXnKMJijBjVo,2578
|
53
57
|
slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py,sha256=2tiRxoC9PYOQn6XQrwK0JTEsb45Pzp2PsKoZSS4rcIA,7564
|
54
58
|
slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py,sha256=N6HYpFBhMckAFLZFW8PY8Us1qzXlauEQiDwEYwd9_K8,1422
|
55
59
|
slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py,sha256=jjQmlRv6nqdm5q6LbwVpSUSkTBj1c76Hiq8e8q77q3g,933
|
56
60
|
slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py,sha256=8Ga3VFgKrzMs_-B8OPtfP-0rey_MFaDg-QGtSbaft3o,640
|
57
61
|
slidge/db/avatar.py,sha256=khMqkhUSLOOAulhWHUtkIlE8asdqUuaY8cieij97Hsw,7640
|
58
|
-
slidge/db/meta.py,sha256
|
59
|
-
slidge/db/models.py,sha256=
|
60
|
-
slidge/db/store.py,sha256=
|
62
|
+
slidge/db/meta.py,sha256=v1Jf-npZ28QwdGpsLQWLBHEbEP3-jnPrygRg05tJ_Iw,1831
|
63
|
+
slidge/db/models.py,sha256=UoQnDYGuwp8VPYpqMKS9uFez_Vc8IMHtLADGlDCXC1Q,13179
|
64
|
+
slidge/db/store.py,sha256=rlDwapJhMM2iOpJsjn371qG14nuwZoS5Scd8txF3rWM,40817
|
61
65
|
slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
|
62
66
|
slidge/group/archive.py,sha256=xGPkdSk8-BT6t6lNVo1FEwiFVAttoxCma8Tsyk5r8Kg,5279
|
63
67
|
slidge/group/bookmarks.py,sha256=NGEOTSrIIzSYVxUp2QlbW4cRNavPCaFLo21WrOjxBPc,6647
|
64
68
|
slidge/group/participant.py,sha256=FhI8RjVMp5fpYMLxG38wWPI3GEke8rTs-tmLklCIpzA,16764
|
65
|
-
slidge/group/room.py,sha256=
|
66
|
-
slidge/main.py,sha256=
|
69
|
+
slidge/group/room.py,sha256=OiV-qex_aGezGwOkKe2Uxscm7LA9F0NrvhRo-y-6Sjw,45232
|
70
|
+
slidge/main.py,sha256=TbkG5m1SgNmfaZ7TOD5VGTh4Q52XltLJayWnan8M9cw,5986
|
67
71
|
slidge/migration.py,sha256=qUrux9dYCtOfFjPIlvGfWjoyqhkdxzaOByJRqTmCoUI,1072
|
68
72
|
slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
69
73
|
slidge/slixfix/__init__.py,sha256=7GevigEt68hwgwHqXcsFogN5jRXRHPeqR6kwODCH4hc,3055
|
70
74
|
slidge/slixfix/link_preview/__init__.py,sha256=TDPTSEH5FQxgGpQpQIde-D72AHg-6YVWG-tOj4KpKmU,290
|
71
75
|
slidge/slixfix/link_preview/link_preview.py,sha256=9PgdfnoyVMHnXS0w5OFp0wz3ku96Ck-HtRXbVUlDi1U,448
|
72
76
|
slidge/slixfix/link_preview/stanza.py,sha256=YAXoNw2MD0a3nzvldGKlvSemjUMbUEG23regzmj4Ntc,2664
|
73
|
-
slidge/slixfix/roster.py,sha256=
|
77
|
+
slidge/slixfix/roster.py,sha256=KvDjh9q7pqaZf69H93okfib13cc95uVZUJ6rzpqmDaU,1704
|
74
78
|
slidge/slixfix/xep_0077/__init__.py,sha256=0lY1YXdgAsfrfxI_Woxaf1etHCJXe35Xtntq_icF6nA,325
|
75
79
|
slidge/slixfix/xep_0077/register.py,sha256=6nwTfHNL7Z9-1wUhpAF743TNbjQLCMP7Rflkdad8d60,10431
|
76
80
|
slidge/slixfix/xep_0077/stanza.py,sha256=Lngly7F1ChCkNKn7yl1QmN838fO-KqkAhkazxzDsz80,2410
|
@@ -84,7 +88,7 @@ slidge/slixfix/xep_0264/__init__.py,sha256=c6g_y-PAwQJZ4ZLWcwXc6Q5xRPeXTvvvJH4ZK
|
|
84
88
|
slidge/slixfix/xep_0264/stanza.py,sha256=YvkI9rsGztkc9yOZBjf5PNKReW8aeGdF6MnrsfDckYs,864
|
85
89
|
slidge/slixfix/xep_0264/thumbnail.py,sha256=6ukgPCWJTFUnew4USB6hNtEk_ZcpWcFAvHr2r0T5znw,456
|
86
90
|
slidge/slixfix/xep_0292/__init__.py,sha256=_MvS9wGra6ig3P_dPAVlCPDJkiOFvUWGjaRsHj1woUg,98
|
87
|
-
slidge/slixfix/xep_0292/vcard4.py,sha256=
|
91
|
+
slidge/slixfix/xep_0292/vcard4.py,sha256=jL-TOW3eG2QXLduSLNq03L8HoUNmvy8kTZI5ojvo6GE,358
|
88
92
|
slidge/slixfix/xep_0313/__init__.py,sha256=rpvXxN4Fi-ey4Ww39OEAXoiaeWs3XMqvzR64hA6j_x4,368
|
89
93
|
slidge/slixfix/xep_0313/mam.py,sha256=2USgMGgklnGXPcw_1F3482HxIyd41TLx0uit43_RthA,9211
|
90
94
|
slidge/slixfix/xep_0313/stanza.py,sha256=WriAx6XKiiyZTkoTw5RHcgu3ZYdkDd6hjQ0wHqDkXE0,10249
|
@@ -103,12 +107,11 @@ slidge/slixfix/xep_0490/stanza.py,sha256=ztec_ipyhUFz_uWQYkS0Q6LlsNiSBBC5aZK-qSm
|
|
103
107
|
slidge/util/__init__.py,sha256=BELovoTMPcPPGz3D48esBr8A4BRRHXTvavfgnArBgEc,301
|
104
108
|
slidge/util/archive_msg.py,sha256=xXAR0BI5r3d6KKWjae9594izCOv6iI03z2WLuTecNw8,1724
|
105
109
|
slidge/util/conf.py,sha256=1j2OnOsCBar1tOObErhXR5RC3Vl3faliOZ1U8J3My58,6613
|
106
|
-
slidge/util/
|
107
|
-
slidge/util/test.py,sha256=yRl3_dmNrn_v-FtOsRo_9eZr3Owj5JB5YIS0PozFU0E,13266
|
110
|
+
slidge/util/test.py,sha256=nCldxi9dLPj-c4LqZChR9DbzXFU4WgT0o_Pe80JJIDc,13279
|
108
111
|
slidge/util/types.py,sha256=Gif-Z9NVd_eTei1uM3_KOsdok3B1yMQwdOkOzf9vheE,5224
|
109
112
|
slidge/util/util.py,sha256=8JeE0QObNGQr_Tw4OFPwQSz_EB_zh_0t9IJmNNhW0ic,9114
|
110
|
-
slidge-0.2.
|
111
|
-
slidge-0.2.
|
112
|
-
slidge-0.2.
|
113
|
-
slidge-0.2.
|
114
|
-
slidge-0.2.
|
113
|
+
slidge-0.2.0a3.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
|
114
|
+
slidge-0.2.0a3.dist-info/METADATA,sha256=FHnY-NweSRtVFdxm75xTdbZD2MieNfqIvlagawopsWM,4723
|
115
|
+
slidge-0.2.0a3.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
116
|
+
slidge-0.2.0a3.dist-info/entry_points.txt,sha256=SNl72KSocF5plsu_67xyH6wVWfGTXQbzkQgXbLtzDrQ,47
|
117
|
+
slidge-0.2.0a3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|