slidge 0.2.12__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 +345 -327
- 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.12.dist-info → slidge-0.3.0.dist-info}/METADATA +1 -1
- slidge-0.3.0.dist-info/RECORD +95 -0
- {slidge-0.2.12.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.12.dist-info/RECORD +0 -112
- {slidge-0.2.12.dist-info → slidge-0.3.0.dist-info}/entry_points.txt +0 -0
- {slidge-0.2.12.dist-info → slidge-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {slidge-0.2.12.dist-info → slidge-0.3.0.dist-info}/top_level.txt +0 -0
slidge/group/archive.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
import logging
|
2
2
|
import uuid
|
3
|
+
import warnings
|
3
4
|
from copy import copy
|
4
5
|
from datetime import datetime, timezone
|
5
6
|
from typing import TYPE_CHECKING, Collection, Optional
|
6
7
|
|
7
8
|
from slixmpp import Iq, Message
|
8
9
|
|
9
|
-
from ..db.models import ArchivedMessage, ArchivedMessageSource
|
10
|
+
from ..db.models import ArchivedMessage, ArchivedMessageSource, Room
|
10
11
|
from ..db.store import MAMStore
|
11
12
|
from ..util.archive_msg import HistoryMessage
|
12
13
|
from ..util.types import HoleBound
|
@@ -16,17 +17,17 @@ if TYPE_CHECKING:
|
|
16
17
|
|
17
18
|
|
18
19
|
class MessageArchive:
|
19
|
-
def __init__(self,
|
20
|
-
self.
|
20
|
+
def __init__(self, room: Room, store: MAMStore) -> None:
|
21
|
+
self.room = room
|
21
22
|
self.__store = store
|
22
23
|
|
23
24
|
def add(
|
24
25
|
self,
|
25
26
|
msg: Message,
|
26
27
|
participant: Optional["LegacyParticipant"] = None,
|
27
|
-
archive_only=False,
|
28
|
+
archive_only: bool = False,
|
28
29
|
legacy_msg_id=None,
|
29
|
-
):
|
30
|
+
) -> None:
|
30
31
|
"""
|
31
32
|
Add a message to the archive if it is deemed archivable
|
32
33
|
|
@@ -39,8 +40,8 @@ class MessageArchive:
|
|
39
40
|
return
|
40
41
|
new_msg = copy(msg)
|
41
42
|
if participant and not participant.muc.is_anonymous:
|
42
|
-
new_msg["muc"]["role"] = participant.role
|
43
|
-
new_msg["muc"]["affiliation"] = participant.affiliation
|
43
|
+
new_msg["muc"]["role"] = participant.role or "participant"
|
44
|
+
new_msg["muc"]["affiliation"] = participant.affiliation or "member"
|
44
45
|
if participant.contact:
|
45
46
|
new_msg["muc"]["jid"] = participant.contact.jid.bare
|
46
47
|
elif participant.is_user:
|
@@ -48,17 +49,22 @@ class MessageArchive:
|
|
48
49
|
elif participant.is_system:
|
49
50
|
new_msg["muc"]["jid"] = participant.muc.jid
|
50
51
|
else:
|
51
|
-
|
52
|
+
warnings.warn(
|
53
|
+
f"No real JID for participant '{participant.nickname}' in '{self.room.name}'"
|
54
|
+
)
|
52
55
|
new_msg["muc"]["jid"] = (
|
53
56
|
f"{uuid.uuid4()}@{participant.xmpp.boundjid.bare}"
|
54
57
|
)
|
55
58
|
|
56
|
-
self.__store.
|
57
|
-
self.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
with self.__store.session() as orm:
|
60
|
+
self.__store.add_message(
|
61
|
+
orm,
|
62
|
+
self.room.id,
|
63
|
+
HistoryMessage(new_msg),
|
64
|
+
archive_only,
|
65
|
+
None if legacy_msg_id is None else str(legacy_msg_id),
|
66
|
+
)
|
67
|
+
orm.commit()
|
62
68
|
|
63
69
|
def __iter__(self):
|
64
70
|
return iter(self.get_all())
|
@@ -71,31 +77,32 @@ class MessageArchive:
|
|
71
77
|
)
|
72
78
|
|
73
79
|
def get_hole_bounds(self) -> tuple[HoleBound | None, HoleBound | None]:
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
self.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
with self.__store.session() as orm:
|
81
|
+
most_recent = self.__store.get_most_recent_with_legacy_id(orm, self.room.id)
|
82
|
+
if most_recent is None:
|
83
|
+
return None, None
|
84
|
+
if most_recent.source == ArchivedMessageSource.BACKFILL:
|
85
|
+
# most recent = only backfill, fetch everything since last backfill
|
86
|
+
return self.__to_bound(most_recent), None
|
87
|
+
|
88
|
+
most_recent_back_filled = self.__store.get_most_recent_with_legacy_id(
|
89
|
+
orm, self.room.id, ArchivedMessageSource.BACKFILL
|
90
|
+
)
|
91
|
+
if most_recent_back_filled is None:
|
92
|
+
# group was never back-filled, fetch everything before first live
|
93
|
+
least_recent_live = self.__store.get_first(orm, self.room.id, True)
|
94
|
+
assert least_recent_live is not None
|
95
|
+
return None, self.__to_bound(least_recent_live)
|
96
|
+
|
97
|
+
assert most_recent_back_filled.legacy_id is not None
|
98
|
+
least_recent_live = self.__store.get_least_recent_with_legacy_id_after(
|
99
|
+
orm, self.room.id, most_recent_back_filled.legacy_id
|
100
|
+
)
|
87
101
|
assert least_recent_live is not None
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
self.room_pk, most_recent_back_filled.legacy_id
|
93
|
-
)
|
94
|
-
assert least_recent_live is not None
|
95
|
-
# this is a hole caused by slidge downtime
|
96
|
-
return self.__to_bound(most_recent_back_filled), self.__to_bound(
|
97
|
-
least_recent_live
|
98
|
-
)
|
102
|
+
# this is a hole caused by slidge downtime
|
103
|
+
return self.__to_bound(most_recent_back_filled), self.__to_bound(
|
104
|
+
least_recent_live
|
105
|
+
)
|
99
106
|
|
100
107
|
def get_all(
|
101
108
|
self,
|
@@ -106,22 +113,24 @@ class MessageArchive:
|
|
106
113
|
ids: Collection[str] = (),
|
107
114
|
last_page_n: Optional[int] = None,
|
108
115
|
sender: Optional[str] = None,
|
109
|
-
flip=False,
|
116
|
+
flip: bool = False,
|
110
117
|
):
|
111
|
-
|
112
|
-
self.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
118
|
+
with self.__store.session() as orm:
|
119
|
+
for msg in self.__store.get_messages(
|
120
|
+
orm,
|
121
|
+
self.room.id,
|
122
|
+
before_id=before_id,
|
123
|
+
after_id=after_id,
|
124
|
+
ids=ids,
|
125
|
+
last_page_n=last_page_n,
|
126
|
+
sender=sender,
|
127
|
+
start_date=start_date,
|
128
|
+
end_date=end_date,
|
129
|
+
flip=flip,
|
130
|
+
):
|
131
|
+
yield msg
|
132
|
+
|
133
|
+
async def send_metadata(self, iq: Iq) -> None:
|
125
134
|
"""
|
126
135
|
Send archive extent, as per the spec
|
127
136
|
|
@@ -129,7 +138,8 @@ class MessageArchive:
|
|
129
138
|
:return:
|
130
139
|
"""
|
131
140
|
reply = iq.reply()
|
132
|
-
|
141
|
+
with self.__store.session() as orm:
|
142
|
+
messages = self.__store.get_first_and_last(orm, self.room.id)
|
133
143
|
if messages:
|
134
144
|
for x, m in [("start", messages[0]), ("end", messages[-1])]:
|
135
145
|
reply["mam_metadata"][x]["id"] = m.id
|
@@ -141,7 +151,7 @@ class MessageArchive:
|
|
141
151
|
reply.send()
|
142
152
|
|
143
153
|
|
144
|
-
def archivable(msg: Message):
|
154
|
+
def archivable(msg: Message) -> bool:
|
145
155
|
"""
|
146
156
|
Determine if a message stanza is worth archiving, ie, convey meaningful
|
147
157
|
info
|
slidge/group/bookmarks.py
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
import abc
|
2
2
|
import logging
|
3
|
-
from typing import TYPE_CHECKING, Generic, Iterator, Optional, Type
|
3
|
+
from typing import TYPE_CHECKING, Generic, Iterator, Literal, Optional, Type, overload
|
4
4
|
|
5
5
|
from slixmpp import JID
|
6
6
|
from slixmpp.exceptions import XMPPError
|
7
7
|
|
8
|
-
from ..core.mixins.lock import NamedLockMixin
|
9
8
|
from ..db.models import Room
|
10
9
|
from ..util import SubclassableOnce
|
11
10
|
from ..util.jid_escaping import ESCAPE_TABLE, unescape_node
|
11
|
+
from ..util.lock import NamedLockMixin
|
12
12
|
from ..util.types import LegacyGroupIdType, LegacyMUCType
|
13
|
-
from .archive import MessageArchive
|
14
13
|
from .room import LegacyMUC
|
15
14
|
|
16
15
|
if TYPE_CHECKING:
|
@@ -26,13 +25,12 @@ class LegacyBookmarks(
|
|
26
25
|
This is instantiated once per :class:`~slidge.BaseSession`
|
27
26
|
"""
|
28
27
|
|
29
|
-
|
28
|
+
_muc_cls: Type[LegacyMUCType]
|
29
|
+
|
30
|
+
def __init__(self, session: "BaseSession") -> None:
|
30
31
|
self.session = session
|
31
32
|
self.xmpp = session.xmpp
|
32
33
|
self.user_jid = session.user_jid
|
33
|
-
self.__store = self.xmpp.store.rooms
|
34
|
-
|
35
|
-
self._muc_class: Type[LegacyMUCType] = LegacyMUC.get_self_or_unique_subclass()
|
36
34
|
|
37
35
|
self._user_nick: str = self.session.user_jid.node
|
38
36
|
|
@@ -47,23 +45,28 @@ class LegacyBookmarks(
|
|
47
45
|
return self._user_nick
|
48
46
|
|
49
47
|
@user_nick.setter
|
50
|
-
def user_nick(self, nick: str):
|
48
|
+
def user_nick(self, nick: str) -> None:
|
51
49
|
self._user_nick = nick
|
52
50
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
51
|
+
def from_store(self, stored: Room) -> LegacyMUCType:
|
52
|
+
return self._muc_cls(self.session, stored)
|
53
|
+
|
54
|
+
def __iter__(self) -> Iterator[LegacyMUC]:
|
55
|
+
with self.xmpp.store.session() as orm:
|
56
|
+
for stored in orm.query(Room).filter_by(user=self.session.user).all():
|
57
|
+
if stored.updated:
|
58
|
+
yield self.from_store(stored)
|
56
59
|
|
57
|
-
def __repr__(self):
|
60
|
+
def __repr__(self) -> str:
|
58
61
|
return f"<Bookmarks of {self.user_jid}>"
|
59
62
|
|
60
|
-
async def legacy_id_to_jid_local_part(self, legacy_id: LegacyGroupIdType):
|
63
|
+
async def legacy_id_to_jid_local_part(self, legacy_id: LegacyGroupIdType) -> str:
|
61
64
|
return await self.legacy_id_to_jid_username(legacy_id)
|
62
65
|
|
63
|
-
async def jid_local_part_to_legacy_id(self, local_part: str):
|
66
|
+
async def jid_local_part_to_legacy_id(self, local_part: str) -> LegacyGroupIdType:
|
64
67
|
return await self.jid_username_to_legacy_id(local_part)
|
65
68
|
|
66
|
-
async def legacy_id_to_jid_username(self, legacy_id: LegacyGroupIdType):
|
69
|
+
async def legacy_id_to_jid_username(self, legacy_id: LegacyGroupIdType) -> str:
|
67
70
|
"""
|
68
71
|
The default implementation calls ``str()`` on the legacy_id and
|
69
72
|
escape characters according to :xep:`0106`.
|
@@ -88,59 +91,92 @@ class LegacyBookmarks(
|
|
88
91
|
if jid.resource:
|
89
92
|
jid = JID(jid.bare)
|
90
93
|
async with self.lock(("bare", jid.bare)):
|
91
|
-
|
92
|
-
legacy_id = await self.jid_local_part_to_legacy_id(jid.user)
|
94
|
+
legacy_id = await self.jid_local_part_to_legacy_id(jid.node)
|
93
95
|
if self.get_lock(("legacy_id", legacy_id)):
|
94
|
-
self.log.debug("
|
96
|
+
self.session.log.debug("Already updating %s via by_legacy_id()", jid)
|
95
97
|
return await self.by_legacy_id(legacy_id)
|
96
98
|
|
97
|
-
with self.
|
98
|
-
stored =
|
99
|
-
|
99
|
+
with self.session.xmpp.store.session() as orm:
|
100
|
+
stored = (
|
101
|
+
orm.query(Room)
|
102
|
+
.filter_by(user_account_id=self.session.user_pk, jid=jid)
|
103
|
+
.one_or_none()
|
104
|
+
)
|
105
|
+
if stored is None:
|
106
|
+
stored = Room(
|
107
|
+
user_account_id=self.session.user_pk,
|
108
|
+
jid=jid,
|
109
|
+
legacy_id=legacy_id,
|
110
|
+
)
|
111
|
+
return await self.__update_if_needed(stored)
|
100
112
|
|
101
113
|
def by_jid_only_if_exists(self, jid: JID) -> Optional[LegacyMUCType]:
|
102
|
-
with self.
|
103
|
-
stored =
|
114
|
+
with self.xmpp.store.session() as orm:
|
115
|
+
stored = (
|
116
|
+
orm.query(Room).filter_by(user=self.session.user, jid=jid).one_or_none()
|
117
|
+
)
|
104
118
|
if stored is not None and stored.updated:
|
105
|
-
return self.
|
119
|
+
return self.from_store(stored)
|
106
120
|
return None
|
107
121
|
|
108
|
-
|
122
|
+
@overload
|
123
|
+
async def by_legacy_id(self, legacy_id: LegacyGroupIdType) -> "LegacyMUCType": ...
|
124
|
+
|
125
|
+
@overload
|
126
|
+
async def by_legacy_id(
|
127
|
+
self, legacy_id: LegacyGroupIdType, create: Literal[False]
|
128
|
+
) -> "LegacyMUCType | None": ...
|
129
|
+
|
130
|
+
@overload
|
131
|
+
async def by_legacy_id(
|
132
|
+
self, legacy_id: LegacyGroupIdType, create: Literal[True]
|
133
|
+
) -> "LegacyMUCType": ...
|
134
|
+
|
135
|
+
async def by_legacy_id(
|
136
|
+
self, legacy_id: LegacyGroupIdType, create: bool = False
|
137
|
+
) -> LegacyMUCType | None:
|
109
138
|
async with self.lock(("legacy_id", legacy_id)):
|
110
139
|
local = await self.legacy_id_to_jid_local_part(legacy_id)
|
111
140
|
jid = JID(f"{local}@{self.xmpp.boundjid}")
|
112
141
|
if self.get_lock(("bare", jid.bare)):
|
113
|
-
self.log.debug("
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
142
|
+
self.session.log.debug("Already updating %s via by_jid()", jid)
|
143
|
+
if create:
|
144
|
+
return await self.by_jid(jid)
|
145
|
+
else:
|
146
|
+
return self.by_jid_only_if_exists(jid)
|
147
|
+
|
148
|
+
with self.xmpp.store.session() as orm:
|
149
|
+
stored = (
|
150
|
+
orm.query(Room)
|
151
|
+
.filter_by(
|
152
|
+
user_account_id=self.session.user_pk,
|
153
|
+
legacy_id=str(legacy_id),
|
154
|
+
)
|
155
|
+
.one_or_none()
|
156
|
+
)
|
157
|
+
if stored is None:
|
158
|
+
stored = Room(
|
159
|
+
user_account_id=self.session.user_pk,
|
160
|
+
jid=jid,
|
161
|
+
legacy_id=str(legacy_id),
|
119
162
|
)
|
120
|
-
|
121
|
-
|
122
|
-
async def
|
123
|
-
self
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
except Exception as e:
|
138
|
-
raise XMPPError("internal-server-error", str(e))
|
139
|
-
if not muc.user_nick:
|
140
|
-
muc.user_nick = self._user_nick
|
141
|
-
self.log.debug("MUC created: %r", muc)
|
142
|
-
muc.pk = self.__store.update(muc)
|
143
|
-
muc.archive = MessageArchive(muc.pk, self.xmpp.store.mam)
|
163
|
+
return await self.__update_if_needed(stored)
|
164
|
+
|
165
|
+
async def __update_if_needed(self, stored: Room) -> LegacyMUCType:
|
166
|
+
muc = self.from_store(stored)
|
167
|
+
if muc.stored.updated:
|
168
|
+
return muc
|
169
|
+
|
170
|
+
with muc.updating_info():
|
171
|
+
try:
|
172
|
+
await muc.update_info()
|
173
|
+
except NotImplementedError:
|
174
|
+
pass
|
175
|
+
except XMPPError:
|
176
|
+
raise
|
177
|
+
except Exception as e:
|
178
|
+
raise XMPPError("internal-server-error", str(e))
|
179
|
+
|
144
180
|
return muc
|
145
181
|
|
146
182
|
@abc.abstractmethod
|
@@ -164,8 +200,8 @@ class LegacyBookmarks(
|
|
164
200
|
async def remove(
|
165
201
|
self,
|
166
202
|
muc: LegacyMUC,
|
167
|
-
reason="You left this group from the official client.",
|
168
|
-
kick=True,
|
203
|
+
reason: str = "You left this group from the official client.",
|
204
|
+
kick: bool = True,
|
169
205
|
) -> None:
|
170
206
|
"""
|
171
207
|
Delete everything about a specific group.
|
@@ -179,8 +215,9 @@ class LegacyBookmarks(
|
|
179
215
|
to False in case you do this somewhere else in your code, eg, on
|
180
216
|
receiving the confirmation that the group was deleted.
|
181
217
|
"""
|
182
|
-
assert muc.pk is not None
|
183
218
|
if kick:
|
184
219
|
user_participant = await muc.get_user_participant()
|
185
220
|
user_participant.kick(reason)
|
186
|
-
self.
|
221
|
+
with self.xmpp.store.session() as orm:
|
222
|
+
orm.delete(muc.stored)
|
223
|
+
orm.commit()
|