slidge 0.1.2__py3-none-any.whl → 0.2.0a0__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 +3 -5
- slidge/__main__.py +2 -196
- slidge/__version__.py +5 -0
- slidge/command/adhoc.py +8 -1
- slidge/command/admin.py +5 -6
- slidge/command/base.py +1 -2
- slidge/command/register.py +32 -16
- slidge/command/user.py +85 -5
- slidge/contact/contact.py +93 -31
- slidge/contact/roster.py +54 -39
- slidge/core/config.py +13 -7
- slidge/core/gateway/base.py +139 -34
- slidge/core/gateway/disco.py +2 -4
- slidge/core/gateway/mam.py +1 -4
- slidge/core/gateway/ping.py +2 -3
- slidge/core/gateway/presence.py +1 -1
- slidge/core/gateway/registration.py +32 -21
- slidge/core/gateway/search.py +3 -5
- slidge/core/gateway/session_dispatcher.py +109 -51
- slidge/core/gateway/vcard_temp.py +6 -4
- slidge/core/mixins/__init__.py +11 -1
- slidge/core/mixins/attachment.py +15 -10
- slidge/core/mixins/avatar.py +66 -18
- slidge/core/mixins/base.py +8 -2
- slidge/core/mixins/message.py +11 -7
- slidge/core/mixins/message_maker.py +17 -9
- slidge/core/mixins/presence.py +14 -4
- slidge/core/pubsub.py +54 -212
- slidge/core/session.py +65 -33
- slidge/db/__init__.py +4 -0
- slidge/db/alembic/env.py +64 -0
- slidge/db/alembic/script.py.mako +26 -0
- slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +36 -0
- slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +37 -0
- slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +133 -0
- slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +76 -0
- slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +214 -0
- slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +26 -0
- slidge/db/avatar.py +224 -0
- slidge/db/meta.py +65 -0
- slidge/db/models.py +365 -0
- slidge/db/store.py +976 -0
- slidge/group/archive.py +13 -14
- slidge/group/bookmarks.py +59 -56
- slidge/group/participant.py +81 -29
- slidge/group/room.py +242 -142
- slidge/main.py +201 -0
- slidge/migration.py +30 -0
- slidge/slixfix/__init__.py +35 -2
- slidge/slixfix/roster.py +11 -4
- slidge/slixfix/xep_0292/vcard4.py +1 -0
- slidge/util/db.py +1 -47
- slidge/util/test.py +21 -4
- slidge/util/types.py +24 -4
- {slidge-0.1.2.dist-info → slidge-0.2.0a0.dist-info}/METADATA +3 -1
- slidge-0.2.0a0.dist-info/RECORD +108 -0
- slidge/core/cache.py +0 -183
- slidge/util/schema.sql +0 -126
- slidge/util/sql.py +0 -508
- slidge-0.1.2.dist-info/RECORD +0 -96
- {slidge-0.1.2.dist-info → slidge-0.2.0a0.dist-info}/LICENSE +0 -0
- {slidge-0.1.2.dist-info → slidge-0.2.0a0.dist-info}/WHEEL +0 -0
- {slidge-0.1.2.dist-info → slidge-0.2.0a0.dist-info}/entry_points.txt +0 -0
slidge/contact/contact.py
CHANGED
@@ -2,7 +2,7 @@ import datetime
|
|
2
2
|
import logging
|
3
3
|
import warnings
|
4
4
|
from datetime import date
|
5
|
-
from typing import TYPE_CHECKING, Generic, Iterable, Optional, Union
|
5
|
+
from typing import TYPE_CHECKING, Generic, Iterable, Optional, Self, Union
|
6
6
|
|
7
7
|
from slixmpp import JID, Message, Presence
|
8
8
|
from slixmpp.exceptions import IqError
|
@@ -10,10 +10,10 @@ from slixmpp.plugins.xep_0292.stanza import VCard4
|
|
10
10
|
from slixmpp.types import MessageTypes
|
11
11
|
|
12
12
|
from ..core import config
|
13
|
-
from ..core.mixins import FullCarbonMixin
|
14
|
-
from ..core.mixins.avatar import AvatarMixin
|
13
|
+
from ..core.mixins import AvatarMixin, FullCarbonMixin, StoredAttributeMixin
|
15
14
|
from ..core.mixins.disco import ContactAccountDiscoMixin
|
16
15
|
from ..core.mixins.recipient import ReactionRecipientMixin, ThreadRecipientMixin
|
16
|
+
from ..db.models import Contact
|
17
17
|
from ..util import SubclassableOnce
|
18
18
|
from ..util.types import LegacyUserIdType, MessageOrPresenceTypeVar
|
19
19
|
|
@@ -24,6 +24,7 @@ if TYPE_CHECKING:
|
|
24
24
|
|
25
25
|
class LegacyContact(
|
26
26
|
Generic[LegacyUserIdType],
|
27
|
+
StoredAttributeMixin,
|
27
28
|
AvatarMixin,
|
28
29
|
ContactAccountDiscoMixin,
|
29
30
|
FullCarbonMixin,
|
@@ -100,7 +101,6 @@ class LegacyContact(
|
|
100
101
|
"""
|
101
102
|
super().__init__()
|
102
103
|
self.session = session
|
103
|
-
self.user = session.user
|
104
104
|
self.legacy_id: LegacyUserIdType = legacy_id
|
105
105
|
"""
|
106
106
|
The legacy identifier of the :term:`Legacy Contact`.
|
@@ -116,16 +116,40 @@ class LegacyContact(
|
|
116
116
|
|
117
117
|
self._name: Optional[str] = None
|
118
118
|
|
119
|
-
if self.xmpp.MARK_ALL_MESSAGES:
|
120
|
-
self._sent_order = list[str]()
|
121
|
-
|
122
119
|
self.xmpp = session.xmpp
|
123
120
|
self.jid = JID(self.jid_username + "@" + self.xmpp.boundjid.bare)
|
124
121
|
self.jid.resource = self.RESOURCE
|
125
|
-
self.log = logging.getLogger(f"{self.
|
126
|
-
self.
|
127
|
-
self.
|
128
|
-
|
122
|
+
self.log = logging.getLogger(f"{self.user_jid.bare}:{self.jid.bare}")
|
123
|
+
self._is_friend: bool = False
|
124
|
+
self.added_to_roster = False
|
125
|
+
|
126
|
+
@property
|
127
|
+
def is_friend(self):
|
128
|
+
return self._is_friend
|
129
|
+
|
130
|
+
@is_friend.setter
|
131
|
+
def is_friend(self, value: bool):
|
132
|
+
if value == self._is_friend:
|
133
|
+
return
|
134
|
+
self._is_friend = value
|
135
|
+
assert self.contact_pk is not None
|
136
|
+
self.xmpp.store.contacts.set_friend(self.contact_pk, value)
|
137
|
+
|
138
|
+
@property
|
139
|
+
def participants(self) -> list["LegacyParticipant"]:
|
140
|
+
assert self.contact_pk is not None
|
141
|
+
from ..group.participant import LegacyParticipant
|
142
|
+
|
143
|
+
return [
|
144
|
+
LegacyParticipant.get_self_or_unique_subclass().from_store(
|
145
|
+
self.session, stored, contact=self
|
146
|
+
)
|
147
|
+
for stored in self.xmpp.store.participants.get_for_contact(self.contact_pk)
|
148
|
+
]
|
149
|
+
|
150
|
+
@property
|
151
|
+
def user_jid(self):
|
152
|
+
return self.session.user_jid
|
129
153
|
|
130
154
|
def __repr__(self):
|
131
155
|
return f"<Contact '{self.legacy_id}'/'{self.jid.bare}'>"
|
@@ -170,7 +194,7 @@ class LegacyContact(
|
|
170
194
|
) -> MessageOrPresenceTypeVar:
|
171
195
|
if carbon and isinstance(stanza, Message):
|
172
196
|
stanza["to"] = self.jid.bare
|
173
|
-
stanza["from"] = self.
|
197
|
+
stanza["from"] = self.user_jid
|
174
198
|
self._privileged_send(stanza)
|
175
199
|
return stanza # type:ignore
|
176
200
|
|
@@ -186,12 +210,13 @@ class LegacyContact(
|
|
186
210
|
n["nick"] = self.name
|
187
211
|
stanza.append(n)
|
188
212
|
if self.xmpp.MARK_ALL_MESSAGES and is_markable(stanza):
|
189
|
-
self.
|
190
|
-
|
213
|
+
assert self.contact_pk is not None
|
214
|
+
self.xmpp.store.contacts.add_to_sent(self.contact_pk, stanza["id"])
|
215
|
+
stanza["to"] = self.user_jid
|
191
216
|
stanza.send()
|
192
217
|
return stanza
|
193
218
|
|
194
|
-
def get_msg_xmpp_id_up_to(self, horizon_xmpp_id: str):
|
219
|
+
def get_msg_xmpp_id_up_to(self, horizon_xmpp_id: str) -> list[str]:
|
195
220
|
"""
|
196
221
|
Return XMPP msg ids sent by this contact up to a given XMPP msg id.
|
197
222
|
|
@@ -205,15 +230,8 @@ class LegacyContact(
|
|
205
230
|
:param horizon_xmpp_id: The latest message
|
206
231
|
:return: A list of XMPP ids or None if horizon_xmpp_id was not found
|
207
232
|
"""
|
208
|
-
|
209
|
-
|
210
|
-
break
|
211
|
-
else:
|
212
|
-
return
|
213
|
-
i += 1
|
214
|
-
res = self._sent_order[:i]
|
215
|
-
self._sent_order = self._sent_order[i:]
|
216
|
-
return res
|
233
|
+
assert self.contact_pk is not None
|
234
|
+
return self.xmpp.store.contacts.pop_sent_up_to(self.contact_pk, horizon_xmpp_id)
|
217
235
|
|
218
236
|
@property
|
219
237
|
def name(self):
|
@@ -229,9 +247,19 @@ class LegacyContact(
|
|
229
247
|
for p in self.participants:
|
230
248
|
p.nickname = n
|
231
249
|
self._name = n
|
232
|
-
|
250
|
+
assert self.contact_pk is not None
|
251
|
+
self.xmpp.store.contacts.update_nick(self.contact_pk, n)
|
252
|
+
self.xmpp.pubsub.broadcast_nick(
|
253
|
+
user_jid=self.user_jid, jid=self.jid.bare, nick=n
|
254
|
+
)
|
255
|
+
|
256
|
+
def _get_cached_avatar_id(self):
|
257
|
+
assert self.contact_pk is not None
|
258
|
+
return self.xmpp.store.contacts.get_avatar_legacy_id(self.contact_pk)
|
233
259
|
|
234
260
|
def _post_avatar_update(self):
|
261
|
+
assert self.contact_pk is not None
|
262
|
+
self.xmpp.store.contacts.set_avatar(self.contact_pk, self._avatar_pk)
|
235
263
|
for p in self.participants:
|
236
264
|
self.log.debug("Propagating new avatar to %s", p.muc)
|
237
265
|
p.send_last_presence(force=True, no_cache_online=True)
|
@@ -283,7 +311,7 @@ class LegacyContact(
|
|
283
311
|
elif country:
|
284
312
|
vcard.add_address(country, locality)
|
285
313
|
|
286
|
-
self.xmpp.vcard.set_vcard(self.jid.bare, vcard, {self.
|
314
|
+
self.xmpp.vcard.set_vcard(self.jid.bare, vcard, {self.user_jid.bare})
|
287
315
|
|
288
316
|
async def add_to_roster(self, force=False):
|
289
317
|
"""
|
@@ -291,7 +319,7 @@ class LegacyContact(
|
|
291
319
|
|
292
320
|
:param force: add even if the contact was already added successfully
|
293
321
|
"""
|
294
|
-
if self.
|
322
|
+
if self.added_to_roster and not force:
|
295
323
|
return
|
296
324
|
if config.NO_ROSTER_PUSH:
|
297
325
|
log.debug("Roster push request by plugin ignored (--no-roster-push)")
|
@@ -303,7 +331,7 @@ class LegacyContact(
|
|
303
331
|
if (n := self.name) is not None:
|
304
332
|
item["name"] = n
|
305
333
|
kw = dict(
|
306
|
-
jid=self.
|
334
|
+
jid=self.user_jid,
|
307
335
|
roster_items={self.jid.bare: item},
|
308
336
|
)
|
309
337
|
try:
|
@@ -325,12 +353,26 @@ class LegacyContact(
|
|
325
353
|
else:
|
326
354
|
# we only broadcast pubsub events for contacts added to the roster
|
327
355
|
# so if something was set before, we need to push it now
|
328
|
-
self.
|
356
|
+
self.added_to_roster = True
|
329
357
|
self.session.create_task(self.__broadcast_pubsub_items())
|
330
358
|
self.send_last_presence()
|
331
359
|
|
332
360
|
async def __broadcast_pubsub_items(self):
|
333
|
-
|
361
|
+
cached_avatar = self.get_cached_avatar()
|
362
|
+
if cached_avatar is not None:
|
363
|
+
await self.xmpp.pubsub.broadcast_avatar(
|
364
|
+
self.jid.bare, self.session.user_jid, cached_avatar
|
365
|
+
)
|
366
|
+
nick = self.name
|
367
|
+
from ..core.pubsub import PepNick
|
368
|
+
|
369
|
+
if nick is not None:
|
370
|
+
pep_nick = PepNick(nick)
|
371
|
+
await self.xmpp.pubsub.broadcast(
|
372
|
+
pep_nick.nick,
|
373
|
+
self.jid.bare,
|
374
|
+
self.session.user_jid,
|
375
|
+
)
|
334
376
|
|
335
377
|
async def _set_roster(self, **kw):
|
336
378
|
try:
|
@@ -350,6 +392,8 @@ class LegacyContact(
|
|
350
392
|
:param text: Optional message from the friend to the user
|
351
393
|
"""
|
352
394
|
self.is_friend = True
|
395
|
+
assert self.contact_pk is not None
|
396
|
+
self.xmpp.store.contacts.set_friend(self.contact_pk, True)
|
353
397
|
self.log.debug("Accepting friend request")
|
354
398
|
presence = self._make_presence(ptype="subscribed", pstatus=text, bare=True)
|
355
399
|
self._send(presence, nick=True)
|
@@ -415,7 +459,7 @@ class LegacyContact(
|
|
415
459
|
their 'friends'".
|
416
460
|
"""
|
417
461
|
for ptype in "unsubscribe", "unsubscribed", "unavailable":
|
418
|
-
self.xmpp.send_presence(pfrom=self.jid, pto=self.
|
462
|
+
self.xmpp.send_presence(pfrom=self.jid, pto=self.user_jid.bare, ptype=ptype) # type: ignore
|
419
463
|
|
420
464
|
async def update_info(self):
|
421
465
|
"""
|
@@ -442,6 +486,24 @@ class LegacyContact(
|
|
442
486
|
"""
|
443
487
|
pass
|
444
488
|
|
489
|
+
@classmethod
|
490
|
+
def from_store(cls, session, stored: Contact, *args, **kwargs) -> Self:
|
491
|
+
contact = cls(
|
492
|
+
session,
|
493
|
+
cls.xmpp.LEGACY_CONTACT_ID_TYPE(stored.legacy_id),
|
494
|
+
stored.jid.username, # type: ignore
|
495
|
+
*args, # type: ignore
|
496
|
+
**kwargs, # type: ignore
|
497
|
+
)
|
498
|
+
contact.contact_pk = stored.id
|
499
|
+
contact._name = stored.nick
|
500
|
+
contact._is_friend = stored.is_friend
|
501
|
+
contact.added_to_roster = stored.added_to_roster
|
502
|
+
if (data := stored.extra_attributes) is not None:
|
503
|
+
contact.deserialize_extra_attributes(data)
|
504
|
+
contact._set_avatar_from_store(stored)
|
505
|
+
return contact
|
506
|
+
|
445
507
|
|
446
508
|
def is_markable(stanza: Union[Message, Presence]):
|
447
509
|
if isinstance(stanza, Presence):
|
slidge/contact/roster.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import asyncio
|
2
2
|
import logging
|
3
|
-
from typing import TYPE_CHECKING, Generic, Optional, Type
|
3
|
+
from typing import TYPE_CHECKING, Generic, Iterator, Optional, Type
|
4
4
|
|
5
5
|
from slixmpp import JID
|
6
6
|
from slixmpp.jid import JID_UNESCAPE_TRANSFORMATIONS, _unescape_node
|
7
7
|
|
8
8
|
from ..core.mixins.lock import NamedLockMixin
|
9
|
+
from ..db.store import ContactStore
|
9
10
|
from ..util import SubclassableOnce
|
10
11
|
from ..util.types import LegacyContactType, LegacyUserIdType
|
11
12
|
from .contact import LegacyContact
|
@@ -43,38 +44,45 @@ class LegacyRoster(
|
|
43
44
|
LegacyContact.get_self_or_unique_subclass()
|
44
45
|
)
|
45
46
|
self._contact_cls.xmpp = session.xmpp
|
47
|
+
self.__store: ContactStore = session.xmpp.store.contacts
|
46
48
|
|
47
49
|
self.session = session
|
48
|
-
self.
|
49
|
-
self._contacts_by_legacy_id: dict[LegacyUserIdType, LegacyContactType] = {}
|
50
|
-
self.log = logging.getLogger(f"{self.session.user.bare_jid}:roster")
|
50
|
+
self.log = logging.getLogger(f"{self.session.user_jid.bare}:roster")
|
51
51
|
self.user_legacy_id: Optional[LegacyUserIdType] = None
|
52
52
|
self.ready: asyncio.Future[bool] = self.session.xmpp.loop.create_future()
|
53
53
|
super().__init__()
|
54
54
|
|
55
55
|
def __repr__(self):
|
56
|
-
return f"<Roster of {self.session.
|
56
|
+
return f"<Roster of {self.session.user_jid}>"
|
57
57
|
|
58
|
-
def __iter__(self):
|
59
|
-
|
58
|
+
def __iter__(self) -> Iterator[LegacyContactType]:
|
59
|
+
with self.__store.session():
|
60
|
+
for stored in self.__store.get_all(user_pk=self.session.user_pk):
|
61
|
+
yield self._contact_cls.from_store(self.session, stored)
|
60
62
|
|
61
63
|
async def __finish_init_contact(
|
62
64
|
self, legacy_id: LegacyUserIdType, jid_username: str, *args, **kwargs
|
63
65
|
):
|
64
66
|
c = self._contact_cls(self.session, legacy_id, jid_username, *args, **kwargs)
|
65
|
-
async with self.lock(("finish", c)):
|
66
|
-
|
67
|
-
self.
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
async with self.lock(("finish", c.legacy_id)):
|
68
|
+
with self.__store.session():
|
69
|
+
stored = self.__store.get_by_legacy_id(
|
70
|
+
self.session.user_pk, str(legacy_id)
|
71
|
+
)
|
72
|
+
if stored is not None and stored.updated:
|
73
|
+
self.log.debug("Already updated %s", c)
|
74
|
+
return self._contact_cls.from_store(self.session, stored)
|
75
|
+
c.contact_pk = self.__store.add(
|
76
|
+
self.session.user_pk, c.legacy_id, c.jid
|
77
|
+
)
|
78
|
+
await c.avatar_wrap_update_info()
|
79
|
+
self.__store.update(c)
|
72
80
|
return c
|
73
81
|
|
74
82
|
def known_contacts(self, only_friends=True) -> dict[str, LegacyContactType]:
|
75
83
|
if only_friends:
|
76
|
-
return {j: c for j, c in self
|
77
|
-
return self
|
84
|
+
return {j: c for j, c in self if c.is_friend} # type:ignore
|
85
|
+
return {c.jid.bare: c for c in self}
|
78
86
|
|
79
87
|
async def by_jid(self, contact_jid: JID) -> LegacyContactType:
|
80
88
|
# """
|
@@ -89,16 +97,17 @@ class LegacyRoster(
|
|
89
97
|
# """
|
90
98
|
username = contact_jid.node
|
91
99
|
async with self.lock(("username", username)):
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
with self.__store.session():
|
101
|
+
stored = self.__store.get_by_jid(self.session.user_pk, contact_jid)
|
102
|
+
if stored is not None and stored.updated:
|
103
|
+
return self._contact_cls.from_store(self.session, stored)
|
104
|
+
|
105
|
+
legacy_id = await self.jid_username_to_legacy_id(username)
|
106
|
+
log.debug("Contact %s not found", contact_jid)
|
107
|
+
if self.get_lock(("legacy_id", legacy_id)):
|
108
|
+
log.debug("Already updating %s", contact_jid)
|
109
|
+
return await self.by_legacy_id(legacy_id)
|
110
|
+
return await self.__finish_init_contact(legacy_id, username)
|
102
111
|
|
103
112
|
async def by_legacy_id(
|
104
113
|
self, legacy_id: LegacyUserIdType, *args, **kwargs
|
@@ -121,20 +130,26 @@ class LegacyRoster(
|
|
121
130
|
if legacy_id == self.user_legacy_id:
|
122
131
|
raise ContactIsUser
|
123
132
|
async with self.lock(("legacy_id", legacy_id)):
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
log.debug("Contact %s not found", legacy_id)
|
128
|
-
if self.get_lock(("username", username)):
|
129
|
-
log.debug("Already updating %s", username)
|
130
|
-
jid = JID()
|
131
|
-
jid.node = username
|
132
|
-
jid.domain = self.session.xmpp.boundjid.bare
|
133
|
-
return await self.by_jid(jid)
|
134
|
-
c = await self.__finish_init_contact(
|
135
|
-
legacy_id, username, *args, **kwargs
|
133
|
+
with self.__store.session():
|
134
|
+
stored = self.__store.get_by_legacy_id(
|
135
|
+
self.session.user_pk, str(legacy_id)
|
136
136
|
)
|
137
|
-
|
137
|
+
if stored is not None and stored.updated:
|
138
|
+
return self._contact_cls.from_store(
|
139
|
+
self.session, stored, *args, **kwargs
|
140
|
+
)
|
141
|
+
|
142
|
+
username = await self.legacy_id_to_jid_username(legacy_id)
|
143
|
+
log.debug("Contact %s not found", legacy_id)
|
144
|
+
if self.get_lock(("username", username)):
|
145
|
+
log.debug("Already updating %s", username)
|
146
|
+
jid = JID()
|
147
|
+
jid.node = username
|
148
|
+
jid.domain = self.session.xmpp.boundjid.bare
|
149
|
+
return await self.by_jid(jid)
|
150
|
+
return await self.__finish_init_contact(
|
151
|
+
legacy_id, username, *args, **kwargs
|
152
|
+
)
|
138
153
|
|
139
154
|
async def by_stanza(self, s) -> LegacyContact:
|
140
155
|
# """
|
slidge/core/config.py
CHANGED
@@ -43,11 +43,18 @@ PORT__SHORT = "p"
|
|
43
43
|
|
44
44
|
HOME_DIR: Path
|
45
45
|
HOME_DIR__DOC = (
|
46
|
-
"
|
46
|
+
"Directory where slidge will writes it persistent data and cache. "
|
47
47
|
"Defaults to /var/lib/slidge/${SLIDGE_JID}. "
|
48
48
|
)
|
49
49
|
HOME_DIR__DYNAMIC_DEFAULT = True
|
50
50
|
|
51
|
+
DB_URL: str
|
52
|
+
DB_URL__DOC = (
|
53
|
+
"Database URL, see <https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls>. "
|
54
|
+
"Defaults to sqlite:///${HOME_DIR}/slidge.sqlite"
|
55
|
+
)
|
56
|
+
DB_URL__DYNAMIC_DEFAULT = True
|
57
|
+
|
51
58
|
USER_JID_VALIDATOR: str
|
52
59
|
USER_JID_VALIDATOR__DOC = (
|
53
60
|
"Regular expression to restrict users that can register to the gateway, by JID. "
|
@@ -70,7 +77,7 @@ UPLOAD_SERVICE__DOC = (
|
|
70
77
|
)
|
71
78
|
|
72
79
|
SECRET_KEY: Optional[str] = None
|
73
|
-
SECRET_KEY__DOC = "Encryption for disk storage"
|
80
|
+
SECRET_KEY__DOC = "Encryption for disk storage. Deprecated."
|
74
81
|
|
75
82
|
NO_ROSTER_PUSH = False
|
76
83
|
NO_ROSTER_PUSH__DOC = "Do not fill users' rosters with legacy contacts automatically"
|
@@ -135,11 +142,13 @@ PARTIAL_REGISTRATION_TIMEOUT__DOC = (
|
|
135
142
|
"a single step registration process is not enough."
|
136
143
|
)
|
137
144
|
|
138
|
-
LAST_SEEN_FALLBACK =
|
145
|
+
LAST_SEEN_FALLBACK = False
|
139
146
|
LAST_SEEN_FALLBACK__DOC = (
|
140
147
|
"When using XEP-0319 (Last User Interaction in Presence), use the presence status"
|
141
148
|
" to display the last seen information in the presence status. Useful for clients"
|
142
|
-
" that do not implement XEP-0319."
|
149
|
+
" that do not implement XEP-0319. Because of implementation details, this can increase"
|
150
|
+
" RAM usage and might be deprecated in the future. Ask your client dev for XEP-0319"
|
151
|
+
" support ;o)."
|
143
152
|
)
|
144
153
|
|
145
154
|
QR_TIMEOUT = 60
|
@@ -211,6 +220,3 @@ DEV_MODE__DOC = (
|
|
211
220
|
"Enables an interactive python shell via chat commands, for admins."
|
212
221
|
"Not safe to use in prod, but great during dev."
|
213
222
|
)
|
214
|
-
|
215
|
-
SYNC_AVATAR = True
|
216
|
-
SYNC_AVATAR__DOC = "Sync the user XMPP avatar to legacy network (if supported)."
|