slidge 0.1.2__py3-none-any.whl → 0.2.0a0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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)."
|