slidge 0.2.0a9__py3-none-any.whl → 0.2.0a10__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. slidge/__version__.py +1 -1
  2. slidge/command/adhoc.py +1 -1
  3. slidge/command/base.py +4 -4
  4. slidge/contact/roster.py +7 -0
  5. slidge/core/dispatcher/__init__.py +3 -0
  6. slidge/core/{gateway → dispatcher}/caps.py +6 -4
  7. slidge/core/{gateway → dispatcher}/disco.py +11 -17
  8. slidge/core/dispatcher/message/__init__.py +10 -0
  9. slidge/core/dispatcher/message/chat_state.py +40 -0
  10. slidge/core/dispatcher/message/marker.py +67 -0
  11. slidge/core/dispatcher/message/message.py +397 -0
  12. slidge/core/dispatcher/muc/__init__.py +12 -0
  13. slidge/core/dispatcher/muc/admin.py +98 -0
  14. slidge/core/{gateway → dispatcher/muc}/mam.py +26 -15
  15. slidge/core/dispatcher/muc/misc.py +118 -0
  16. slidge/core/dispatcher/muc/owner.py +96 -0
  17. slidge/core/{gateway → dispatcher/muc}/ping.py +10 -15
  18. slidge/core/dispatcher/presence.py +177 -0
  19. slidge/core/{gateway → dispatcher}/registration.py +23 -2
  20. slidge/core/{gateway → dispatcher}/search.py +9 -14
  21. slidge/core/dispatcher/session_dispatcher.py +84 -0
  22. slidge/core/dispatcher/util.py +174 -0
  23. slidge/core/{gateway/vcard_temp.py → dispatcher/vcard.py} +26 -12
  24. slidge/core/{gateway/base.py → gateway.py} +42 -137
  25. slidge/core/mixins/base.py +2 -2
  26. slidge/core/mixins/message.py +10 -4
  27. slidge/core/pubsub.py +2 -1
  28. slidge/core/session.py +28 -2
  29. slidge/db/alembic/versions/45c24cc73c91_add_bob.py +42 -0
  30. slidge/db/models.py +13 -0
  31. slidge/db/store.py +128 -2
  32. slidge/{core/gateway → slixfix}/delivery_receipt.py +1 -1
  33. slidge/util/test.py +5 -1
  34. slidge/util/types.py +6 -0
  35. slidge/util/util.py +5 -2
  36. {slidge-0.2.0a9.dist-info → slidge-0.2.0a10.dist-info}/METADATA +2 -1
  37. {slidge-0.2.0a9.dist-info → slidge-0.2.0a10.dist-info}/RECORD +40 -31
  38. slidge/core/gateway/__init__.py +0 -3
  39. slidge/core/gateway/muc_admin.py +0 -35
  40. slidge/core/gateway/presence.py +0 -95
  41. slidge/core/gateway/session_dispatcher.py +0 -895
  42. {slidge-0.2.0a9.dist-info → slidge-0.2.0a10.dist-info}/LICENSE +0 -0
  43. {slidge-0.2.0a9.dist-info → slidge-0.2.0a10.dist-info}/WHEEL +0 -0
  44. {slidge-0.2.0a9.dist-info → slidge-0.2.0a10.dist-info}/entry_points.txt +0 -0
@@ -6,8 +6,8 @@ from slixmpp import JID
6
6
  from ...util.types import MessageOrPresenceTypeVar
7
7
 
8
8
  if TYPE_CHECKING:
9
- from slidge.core.gateway import BaseGateway
10
- from slidge.core.session import BaseSession
9
+ from ..gateway import BaseGateway
10
+ from ..session import BaseSession
11
11
 
12
12
 
13
13
  class MetaBase(ABCMeta):
@@ -214,7 +214,7 @@ class ContentMessageMixin(AttachmentMixin):
214
214
  :param archive_only: (only in groups) Do not send this message to user,
215
215
  but store it in the archive. Meant to be used during ``MUC.backfill()``
216
216
  """
217
- if carbon:
217
+ if carbon and not hasattr(self, "muc"):
218
218
  if not correction and self.xmpp.store.sent.was_sent_by_user(
219
219
  self.session.user_pk, str(legacy_msg_id)
220
220
  ):
@@ -223,6 +223,11 @@ class ContentMessageMixin(AttachmentMixin):
223
223
  legacy_msg_id,
224
224
  )
225
225
  return
226
+ if hasattr(self, "muc") and not self.is_user: # type:ignore
227
+ log.warning(
228
+ "send_text() called with carbon=True on a participant who is not the user",
229
+ legacy_msg_id,
230
+ )
226
231
  self.xmpp.store.sent.set_message(
227
232
  self.session.user_pk,
228
233
  str(legacy_msg_id),
@@ -352,11 +357,12 @@ class ContentMessageMixin(AttachmentMixin):
352
357
  class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
353
358
  def _privileged_send(self, msg: Message):
354
359
  i = msg.get_id()
355
- if not i:
356
- i = str(uuid.uuid4())
360
+ if i:
361
+ self.session.ignore_messages.add(i)
362
+ else:
363
+ i = "slidge-carbon-" + str(uuid.uuid4())
357
364
  msg.set_id(i)
358
365
  msg.del_origin_id()
359
- self.session.ignore_messages.add(i)
360
366
  try:
361
367
  self.xmpp["xep_0356"].send_privileged_message(msg)
362
368
  except PermissionError:
slidge/core/pubsub.py CHANGED
@@ -25,8 +25,9 @@ from ..db.store import ContactStore, SlidgeStore
25
25
  from .mixins.lock import NamedLockMixin
26
26
 
27
27
  if TYPE_CHECKING:
28
+ from slidge.core.gateway import BaseGateway
29
+
28
30
  from ..contact.contact import LegacyContact
29
- from ..core.gateway.base import BaseGateway
30
31
 
31
32
  VCARD4_NAMESPACE = "urn:xmpp:vcard4"
32
33
 
slidge/core/session.py CHANGED
@@ -31,6 +31,7 @@ from ..util.types import (
31
31
  PseudoPresenceShow,
32
32
  RecipientType,
33
33
  ResourceDict,
34
+ Sticker,
34
35
  )
35
36
  from ..util.util import deprecated
36
37
 
@@ -225,6 +226,31 @@ class BaseSession(
225
226
 
226
227
  send_file = deprecated("BaseSession.send_file", on_file)
227
228
 
229
+ async def on_sticker(
230
+ self,
231
+ chat: RecipientType,
232
+ sticker: Sticker,
233
+ *,
234
+ reply_to_msg_id: Optional[LegacyMessageType] = None,
235
+ reply_to_fallback_text: Optional[str] = None,
236
+ reply_to: Optional[Union["LegacyContact", "LegacyParticipant"]] = None,
237
+ thread: Optional[LegacyThreadType] = None,
238
+ ) -> Optional[LegacyMessageType]:
239
+ """
240
+ Triggered when the user sends a file using HTTP Upload (:xep:`0363`)
241
+
242
+ :param chat: See :meth:`.BaseSession.on_text`
243
+ :param sticker: The sticker sent by the user.
244
+ :param reply_to_msg_id: See :meth:`.BaseSession.on_text`
245
+ :param reply_to_fallback_text: See :meth:`.BaseSession.on_text`
246
+ :param reply_to: See :meth:`.BaseSession.on_text`
247
+ :param thread:
248
+
249
+ :return: An ID of some sort that can be used later to ack and mark the message
250
+ as read by the user
251
+ """
252
+ raise NotImplementedError
253
+
228
254
  async def on_active(
229
255
  self, chat: RecipientType, thread: Optional[LegacyThreadType] = None
230
256
  ):
@@ -729,8 +755,8 @@ class BaseSession(
729
755
  self.xmpp.re_login(self)
730
756
 
731
757
  async def get_contact_or_group_or_participant(self, jid: JID, create=True):
732
- if jid.bare in (contacts := self.contacts.known_contacts(only_friends=False)):
733
- return contacts[jid.bare]
758
+ if (contact := self.contacts.by_jid_only_if_exists(jid)) is not None:
759
+ return contact
734
760
  if (muc := self.bookmarks.by_jid_only_if_exists(JID(jid.bare))) is not None:
735
761
  return await self.__get_muc_or_participant(muc, jid)
736
762
  else:
@@ -0,0 +1,42 @@
1
+ """Add BoB
2
+
3
+ Revision ID: 45c24cc73c91
4
+ Revises: 3071e0fa69d4
5
+ Create Date: 2024-08-01 22:30:07.073935
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 = "45c24cc73c91"
16
+ down_revision: Union[str, None] = "3071e0fa69d4"
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
+ op.create_table(
24
+ "bob",
25
+ sa.Column("id", sa.Integer(), nullable=False),
26
+ sa.Column("file_name", sa.String(), nullable=False),
27
+ sa.Column("sha_1", sa.String(), nullable=False),
28
+ sa.Column("sha_256", sa.String(), nullable=False),
29
+ sa.Column("sha_512", sa.String(), nullable=False),
30
+ sa.Column("content_type", sa.String(), nullable=False),
31
+ sa.PrimaryKeyConstraint("id"),
32
+ sa.UniqueConstraint("sha_1"),
33
+ sa.UniqueConstraint("sha_256"),
34
+ sa.UniqueConstraint("sha_512"),
35
+ )
36
+ # ### end Alembic commands ###
37
+
38
+
39
+ def downgrade() -> None:
40
+ # ### commands auto generated by Alembic - please adjust! ###
41
+ op.drop_table("bob")
42
+ # ### end Alembic commands ###
slidge/db/models.py CHANGED
@@ -386,3 +386,16 @@ class Participant(Base):
386
386
  )
387
387
 
388
388
  extra_attributes: Mapped[Optional[JSONSerializable]] = mapped_column(default=None)
389
+
390
+
391
+ class Bob(Base):
392
+ __tablename__ = "bob"
393
+
394
+ id: Mapped[int] = mapped_column(primary_key=True)
395
+ file_name: Mapped[str] = mapped_column(nullable=False)
396
+
397
+ sha_1: Mapped[str] = mapped_column(nullable=False, unique=True)
398
+ sha_256: Mapped[str] = mapped_column(nullable=False, unique=True)
399
+ sha_512: Mapped[str] = mapped_column(nullable=False, unique=True)
400
+
401
+ content_type: Mapped[Optional[str]] = mapped_column(nullable=False)
slidge/db/store.py CHANGED
@@ -1,27 +1,33 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import hashlib
3
4
  import json
4
5
  import logging
6
+ import uuid
5
7
  from contextlib import contextmanager
6
8
  from datetime import datetime, timedelta, timezone
9
+ from mimetypes import guess_extension
7
10
  from typing import TYPE_CHECKING, Collection, Iterator, Optional, Type
8
11
 
9
12
  from slixmpp import JID, Iq, Message, Presence
10
13
  from slixmpp.exceptions import XMPPError
14
+ from slixmpp.plugins.xep_0231.stanza import BitsOfBinary
11
15
  from sqlalchemy import Engine, delete, select, update
12
- from sqlalchemy.orm import Session, attributes
16
+ from sqlalchemy.orm import Session, attributes, load_only
13
17
  from sqlalchemy.sql.functions import count
14
18
 
19
+ from ..core import config
15
20
  from ..util.archive_msg import HistoryMessage
16
21
  from ..util.types import URL, CachedPresence, ClientType
17
22
  from ..util.types import Hat as HatTuple
18
- from ..util.types import MamMetadata, MucAffiliation, MucRole
23
+ from ..util.types import MamMetadata, MucAffiliation, MucRole, Sticker
19
24
  from .meta import Base
20
25
  from .models import (
21
26
  ArchivedMessage,
22
27
  ArchivedMessageSource,
23
28
  Attachment,
24
29
  Avatar,
30
+ Bob,
25
31
  Contact,
26
32
  ContactSent,
27
33
  GatewayUser,
@@ -87,6 +93,7 @@ class SlidgeStore(EngineMixin):
87
93
  self.rooms = RoomStore(engine)
88
94
  self.sent = SentStore(engine)
89
95
  self.participants = ParticipantStore(engine)
96
+ self.bob = BobStore(engine)
90
97
 
91
98
 
92
99
  class UserStore(EngineMixin):
@@ -973,6 +980,15 @@ class RoomStore(UpdatedMixin):
973
980
  select(Room).where(Room.user_account_id == user_pk)
974
981
  ).scalars()
975
982
 
983
+ def get_all_jid_and_names(self, user_pk: int) -> Iterator[Room]:
984
+ with self.session() as session:
985
+ yield from session.scalars(
986
+ select(Room)
987
+ .filter(Room.user_account_id == user_pk)
988
+ .options(load_only(Room.jid, Room.name))
989
+ .order_by(Room.name)
990
+ ).all()
991
+
976
992
 
977
993
  class ParticipantStore(EngineMixin):
978
994
  def __init__(self, *a, **kw):
@@ -1120,5 +1136,115 @@ class ParticipantStore(EngineMixin):
1120
1136
  ).scalar()
1121
1137
 
1122
1138
 
1139
+ class BobStore(EngineMixin):
1140
+ _ATTR_MAP = {
1141
+ "sha-1": "sha_1",
1142
+ "sha1": "sha_1",
1143
+ "sha-256": "sha_256",
1144
+ "sha256": "sha_256",
1145
+ "sha-512": "sha_512",
1146
+ "sha512": "sha_512",
1147
+ }
1148
+
1149
+ _ALG_MAP = {
1150
+ "sha_1": hashlib.sha1,
1151
+ "sha_256": hashlib.sha256,
1152
+ "sha_512": hashlib.sha512,
1153
+ }
1154
+
1155
+ def __init__(self, *a, **k):
1156
+ super().__init__(*a, **k)
1157
+ self.root_dir = config.HOME_DIR / "slidge_stickers"
1158
+ self.root_dir.mkdir(exist_ok=True)
1159
+
1160
+ @staticmethod
1161
+ def __split_cid(cid: str) -> list[str]:
1162
+ return cid.removesuffix("@bob.xmpp.org").split("+")
1163
+
1164
+ def __get_condition(self, cid: str):
1165
+ alg_name, digest = self.__split_cid(cid)
1166
+ attr = self._ATTR_MAP.get(alg_name)
1167
+ if attr is None:
1168
+ log.warning("Unknown hash algo: %s", alg_name)
1169
+ return None
1170
+ return getattr(Bob, attr) == digest
1171
+
1172
+ def get(self, cid: str) -> Bob | None:
1173
+ with self.session() as session:
1174
+ try:
1175
+ return session.query(Bob).filter(self.__get_condition(cid)).scalar()
1176
+ except ValueError:
1177
+ log.warning("Cannot get Bob with CID: %s", cid)
1178
+ return None
1179
+
1180
+ def get_sticker(self, cid: str) -> Sticker | None:
1181
+ bob = self.get(cid)
1182
+ if bob is None:
1183
+ return None
1184
+ return Sticker(
1185
+ self.root_dir / bob.file_name,
1186
+ bob.content_type,
1187
+ {h: getattr(bob, h) for h in self._ALG_MAP},
1188
+ )
1189
+
1190
+ def get_bob(self, _jid, _node, _ifrom, cid: str) -> BitsOfBinary | None:
1191
+ stored = self.get(cid)
1192
+ if stored is None:
1193
+ return None
1194
+ bob = BitsOfBinary()
1195
+ bob["data"] = (self.root_dir / stored.file_name).read_bytes()
1196
+ if stored.content_type is not None:
1197
+ bob["type"] = stored.content_type
1198
+ bob["cid"] = cid
1199
+ return bob
1200
+
1201
+ def del_bob(self, _jid, _node, _ifrom, cid: str) -> None:
1202
+ with self.session() as orm:
1203
+ try:
1204
+ file_name = orm.scalar(
1205
+ delete(Bob)
1206
+ .where(self.__get_condition(cid))
1207
+ .returning(Bob.file_name)
1208
+ )
1209
+ except ValueError:
1210
+ log.warning("Cannot delete Bob with CID: %s", cid)
1211
+ return None
1212
+ if file_name is None:
1213
+ log.warning("No BoB with CID: %s", cid)
1214
+ return None
1215
+ (self.root_dir / file_name).unlink()
1216
+ orm.commit()
1217
+
1218
+ def set_bob(self, _jid, _node, _ifrom, bob: BitsOfBinary) -> None:
1219
+ cid = bob["cid"]
1220
+ try:
1221
+ alg_name, digest = self.__split_cid(cid)
1222
+ except ValueError:
1223
+ log.warning("Cannot set Bob with CID: %s", cid)
1224
+ return
1225
+ attr = self._ATTR_MAP.get(alg_name)
1226
+ if attr is None:
1227
+ log.warning("Cannot set BoB with unknown hash algo: %s", alg_name)
1228
+ return None
1229
+ with self.session() as orm:
1230
+ existing = self.get(bob["cid"])
1231
+ if existing is not None:
1232
+ log.debug("Bob already known")
1233
+ return
1234
+ bytes_ = bob["data"]
1235
+ path = self.root_dir / uuid.uuid4().hex
1236
+ if bob["type"]:
1237
+ path = path.with_suffix(guess_extension(bob["type"]) or "")
1238
+ path.write_bytes(bytes_)
1239
+ hashes = {k: v(bytes_).hexdigest() for k, v in self._ALG_MAP.items()}
1240
+ if hashes[attr] != digest:
1241
+ raise ValueError(
1242
+ "The given CID does not correspond to the result of our hash"
1243
+ )
1244
+ row = Bob(file_name=path.name, content_type=bob["type"] or None, **hashes)
1245
+ orm.add(row)
1246
+ orm.commit()
1247
+
1248
+
1123
1249
  log = logging.getLogger(__name__)
1124
1250
  _session: Optional[Session] = None
@@ -11,7 +11,7 @@ from slixmpp import JID, Message
11
11
  from slixmpp.types import MessageTypes
12
12
 
13
13
  if TYPE_CHECKING:
14
- from .base import BaseGateway
14
+ from slidge.core.gateway import BaseGateway
15
15
 
16
16
 
17
17
  class DeliveryReceipt:
slidge/util/test.py CHANGED
@@ -287,7 +287,11 @@ class SlidgeTest(SlixTestPlus):
287
287
  session.execute(delete(Contact))
288
288
  session.commit()
289
289
 
290
- self.run_coro(self.xmpp._on_user_register(Iq(sfrom="romeo@montague.lit/gajim")))
290
+ self.run_coro(
291
+ self.xmpp._BaseGateway__dispatcher._on_user_register(
292
+ Iq(sfrom="romeo@montague.lit/gajim")
293
+ )
294
+ )
291
295
  welcome = self.next_sent()
292
296
  assert welcome["body"]
293
297
  stanza = self.next_sent()
slidge/util/types.py CHANGED
@@ -207,3 +207,9 @@ class CachedPresence(NamedTuple):
207
207
  ptype: Optional[PresenceTypes] = None
208
208
  pstatus: Optional[str] = None
209
209
  pshow: Optional[PresenceShows] = None
210
+
211
+
212
+ class Sticker(NamedTuple):
213
+ path: Path
214
+ content_type: Optional[str]
215
+ hashes: dict[str, str]
slidge/util/util.py CHANGED
@@ -7,7 +7,7 @@ from abc import ABCMeta
7
7
  from functools import wraps
8
8
  from pathlib import Path
9
9
  from time import time
10
- from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Type
10
+ from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Type, TypeVar
11
11
 
12
12
  from .types import Mention, ResourceDict
13
13
 
@@ -276,7 +276,10 @@ def deprecated(name: str, new: Callable):
276
276
  return wrapped
277
277
 
278
278
 
279
- def dict_to_named_tuple(data: dict, cls: Type[NamedTuple]):
279
+ T = TypeVar("T", bound=NamedTuple)
280
+
281
+
282
+ def dict_to_named_tuple(data: dict, cls: Type[T]) -> T:
280
283
  return cls(*(data.get(f) for f in cls._fields)) # type:ignore
281
284
 
282
285
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slidge
3
- Version: 0.2.0a9
3
+ Version: 0.2.0a10
4
4
  Summary: XMPP bridging framework
5
5
  Home-page: https://sr.ht/~nicoco/slidge/
6
6
  License: AGPL-3.0-or-later
@@ -16,6 +16,7 @@ Requires-Dist: ConfigArgParse (>=1.5.3,<2.0.0)
16
16
  Requires-Dist: Pillow (>=10,<11)
17
17
  Requires-Dist: aiohttp[speedups] (>=3.8.3,<4.0.0)
18
18
  Requires-Dist: alembic (>=1.13.1,<2.0.0)
19
+ Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
19
20
  Requires-Dist: pickle-secure (>=0.99.9,<0.100.0)
20
21
  Requires-Dist: python-magic (>=0.4.27,<0.5.0)
21
22
  Requires-Dist: qrcode (>=7.4.1,<8.0.0)
@@ -1,45 +1,52 @@
1
1
  slidge/__init__.py,sha256=S0tUjqpZlzsr8G4Y_1Xt-KCYB07qaknTB0OwHU8k29U,1587
2
2
  slidge/__main__.py,sha256=Y12eh1TD_C5MB50KgEAuMffGnRFCvKYFKHD4UYSmHA0,72
3
- slidge/__version__.py,sha256=9y4M-LYXgK7-PIasL6QWLN6L5LRaek-yXy_SekzwWrg,170
3
+ slidge/__version__.py,sha256=05G747WHKOvpl1x4M5U-3t3qszlgbNfnUxAxrATG8ck,171
4
4
  slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
5
- slidge/command/adhoc.py,sha256=5xLLoWyUJqCJB7kAwD2VKYTl_7MObCsgdz-qg_WkWGs,9417
5
+ slidge/command/adhoc.py,sha256=9PsTsGMPKAK_YXQpwdcH9SSDki8YQ49OZ5p65W5HA6k,9412
6
6
  slidge/command/admin.py,sha256=x_kJ0TJhzf6d3OBIOXFjudZFO8bRYUG919td7OjMCug,6008
7
- slidge/command/base.py,sha256=xTlzxAbTWTpbFgQ0FxKjmp3ZImzempwJvGn9UiVUUTc,13044
7
+ slidge/command/base.py,sha256=7NSzPZdBLZElrm3smzvFKgP0GUggxXdkhclxIKCjtT8,13036
8
8
  slidge/command/categories.py,sha256=BJCfaga2qoAxnHfgHD7I_RKZuBA5nnNOukkWHJwsUFE,99
9
9
  slidge/command/chat_command.py,sha256=VBs6IuDka1IyyMzz0ZyE9zMImaEzUZLcnffxq_vwb4M,10565
10
10
  slidge/command/register.py,sha256=fzPcGUoJtainnDOiC13gWV-uYLuJcsmdKGJ-jXT1qIo,6697
11
11
  slidge/command/user.py,sha256=uFheYOprhypkHEEl6qSTEM7T2N28xXaDi7v1he-AET8,11512
12
12
  slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
13
13
  slidge/contact/contact.py,sha256=kKtJ9NPLS9DPVyyahx_K-Mtp5k5UQdQJZavC1XCmWlc,23104
14
- slidge/contact/roster.py,sha256=YF5NiParDKYNqW52fu1xSVW1skR-guy7YzIQ5kDYoDk,9874
14
+ slidge/contact/roster.py,sha256=AQTfmM4hrlxkXSM7ZX-C8P9NDN5RqNMNuPrSjt_3MJM,10223
15
15
  slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
16
16
  slidge/core/config.py,sha256=leNcN_TI0Ka1hhzOHx7cBW3fNj5xZwsiv9l8AfRY_vU,7630
17
- slidge/core/gateway/__init__.py,sha256=rZckY2gAE-mon77_DSsAW1XtWqhBAETE2d4FqZ8pJXk,58
18
- slidge/core/gateway/base.py,sha256=Dxy39bAgOvJ-vN1RA9PU821YYuvkp_V06y_-vUDW7bU,38752
19
- slidge/core/gateway/caps.py,sha256=jemB4tB_2MTAxqQw5Bs4b7qNQ8gLPuAve0aoH6TzLEs,1937
20
- slidge/core/gateway/delivery_receipt.py,sha256=AT_9gvZrtWpSRsDJcYjE8CmF7TW-YBbUPdqNW5zWAdo,1352
21
- slidge/core/gateway/disco.py,sha256=uazgDXSDb5KrardjPCvElItARcxkeBRohtx82A2BlCQ,2203
22
- slidge/core/gateway/mam.py,sha256=ZUZXX7YcpK1WHq8RlgYrXo2zrLm5pOM1sVzON61mXYQ,2418
23
- slidge/core/gateway/muc_admin.py,sha256=PslX1gZK_PhY2VaeAPP1nEzThMaBBGPRgs-wiJ35zJQ,1033
24
- slidge/core/gateway/ping.py,sha256=_zzPkjqvxjTxLNP1jbj0WVLMaybxbYqrKDRM5jHSDjs,1729
25
- slidge/core/gateway/presence.py,sha256=Ls8IY4uNQaW8F3F1CpRhfyFIVbd_py_VkZyJKMMei8s,2732
26
- slidge/core/gateway/registration.py,sha256=JXwIQ-QqZCPXEmCU2G8FvIYDGvD8L8CqGb_Qkbycgt0,2303
27
- slidge/core/gateway/search.py,sha256=08ds6gvzX3EnTH-AU8X8J8JKEKYaSrRGTFwwClTT-Rc,3495
28
- slidge/core/gateway/session_dispatcher.py,sha256=FBCbMNNa3SQCd2n_NEdD5q7cjdEgUHGuI_DIWh5cTUY,33202
29
- slidge/core/gateway/vcard_temp.py,sha256=cnzHZO6qF8OUWSvBieEdNAV_Ndv1ixZOzBCBXy2Vopw,4637
17
+ slidge/core/dispatcher/__init__.py,sha256=1EXcjXietUKlxEqdrCWCV3xZ3q_DSsjHoqWrPMbtYao,84
18
+ slidge/core/dispatcher/caps.py,sha256=vzCAXo_bhALuLEpJWtyJTzVfWx96g1AsWD8_wkoDl0Y,2028
19
+ slidge/core/dispatcher/disco.py,sha256=j56VY9NIFzwPEWFKQQZ7YIqS9GdD-ZaF_K8a2L-JvRk,2006
20
+ slidge/core/dispatcher/message/__init__.py,sha256=vpDGOc_U9XvkUU_ws9n9-5M2NPJ87XGTVpuIxM7Z99k,223
21
+ slidge/core/dispatcher/message/chat_state.py,sha256=sCdEpzbgmvBmTovNOCv9uY6v0eJZcWVvDYAGlAV3FJ4,1735
22
+ slidge/core/dispatcher/message/marker.py,sha256=VbD1-2QeOCC4EbrS-wpJxHwIcmvPF4Q4qd0eiv95c7I,2451
23
+ slidge/core/dispatcher/message/message.py,sha256=HwauW2kGionLyDWG01OSa9a14gYzoovJuJvGbfB4nt4,15296
24
+ slidge/core/dispatcher/muc/__init__.py,sha256=V8URHLJ_y7mk-7Id6FzRuczb1Uq_Z69fhxvzHuVLH1w,269
25
+ slidge/core/dispatcher/muc/admin.py,sha256=s21V2LEqc0e_DIpipEhhQdpae762lW1lVqj4wjFhX8M,3364
26
+ slidge/core/dispatcher/muc/mam.py,sha256=1ROVP4ZPEVEH-HR5qRV4YwHz-V15uu5gyhv1ZwwKhk8,2821
27
+ slidge/core/dispatcher/muc/misc.py,sha256=L5I2nt23qvQ-2qS5qgW3hSg6Z7DKnGvwxgXqn_WLvpQ,3943
28
+ slidge/core/dispatcher/muc/owner.py,sha256=Vwwz15fdLq40XTnyDcMmRtMOXdY3T3_BwpSV3Nr8FNw,3290
29
+ slidge/core/dispatcher/muc/ping.py,sha256=lb1VQPhiUPZ19KhbofRXMVCcY6wwQ2w-asnqtANaAwA,1660
30
+ slidge/core/dispatcher/presence.py,sha256=ZxAmC34yxKxbk_-h6g_S8pTssL7ovULm3q2ishpYaB4,6393
31
+ slidge/core/dispatcher/registration.py,sha256=Xmbw9NF3LUppCOa3XzreopdKDitZnwl_5HE-kds74n8,3155
32
+ slidge/core/dispatcher/search.py,sha256=9cGj0wwvyYlP_Yk440Y12sgo4Y1p-JWUDSJP5Zxch0M,3296
33
+ slidge/core/dispatcher/session_dispatcher.py,sha256=_njTftgpUKKMP-hgAo99Hu0YrIa6E9OTzSYdiMW000w,2844
34
+ slidge/core/dispatcher/util.py,sha256=x_vC7OXcaDaSz3RPPGnK9fOvimmMaKPM3RkgmHvU0Qw,5676
35
+ slidge/core/dispatcher/vcard.py,sha256=Rmx-wCz6Lps0mXCO48HppNQlS3GOgMuzuw9hZYBdlVU,5130
36
+ slidge/core/gateway.py,sha256=NhIgxZKPnOpwsx50OKgyZyk9nfU8ZlUSMddwIDIhFcw,36351
30
37
  slidge/core/mixins/__init__.py,sha256=muReAzgvENgMvlfm0Fpe6BQFfm2EMjoDe9ZhGgo6Vig,627
31
38
  slidge/core/mixins/attachment.py,sha256=5Xa_GkSL_rRTC45TRjW98jztk__4M5P-3EG4IF91K0c,19022
32
39
  slidge/core/mixins/avatar.py,sha256=kGIIZzLSNuxF9bIvt5Bv03_uT_pU5QV1kS7cRu6-GUA,7874
33
- slidge/core/mixins/base.py,sha256=9hjf2Pw5r0poSi1Abv-_znk83Kngsu9EXTf05gpFDdI,768
40
+ slidge/core/mixins/base.py,sha256=MOd-pas38_52VawQVlxWtBtmTKC6My9G0ZaCeQxOJbs,748
34
41
  slidge/core/mixins/db.py,sha256=5Qpegd7D8e5TLXLLINYcf_DuVdN-7wNmsfztUuFYPcU,442
35
42
  slidge/core/mixins/disco.py,sha256=jk3Z1B6zTuisHv8VKNRJodIo0ee5btYHh2ZrlflPj_Q,3670
36
43
  slidge/core/mixins/lock.py,sha256=mVzwVVEoq1hrAMgGLh4K84BTLt7JTJ33B8HSGSorTdY,913
37
- slidge/core/mixins/message.py,sha256=jJz_peNQmDf0uVQcI7TWG7oUaSGjUL8eiulNicGgWhI,15071
44
+ slidge/core/mixins/message.py,sha256=6X0MskF1fC9Ih8aLRfdqNe7H3jpnFGEJb0EykRKze0c,15384
38
45
  slidge/core/mixins/message_maker.py,sha256=TcCutHi0sIwL6beJNkN7XyR0aDIbA0xZyxd2Gc9ulG4,6022
39
46
  slidge/core/mixins/presence.py,sha256=yywo6KAw8C7GaZSMrSMuioNfhW08MrnobHt8XbHd0q8,7891
40
47
  slidge/core/mixins/recipient.py,sha256=U-YppozUO8pA94jmD3-qmhkykTebPNaOVWc3JDPC9w8,1302
41
- slidge/core/pubsub.py,sha256=ITOhgUKdYh6oJBpmZ8nevDQlYT4WJMC-k7Z76YchXqY,11906
42
- slidge/core/session.py,sha256=iYRdG_CZYiH-a4A69vqKLf-vnSF_N-XnxEF1veBMCWk,27182
48
+ slidge/core/pubsub.py,sha256=oTiS5KFQJAmsgkhOsvfvthT-LkuZGQSCrrUG0JskNkI,11907
49
+ slidge/core/session.py,sha256=nQexpCd1jlHOhQPnFI4ri-5odp3N2pU5HO4l7WFetZY,28148
43
50
  slidge/db/__init__.py,sha256=EBDH1JSEhgqYcli2Bw11CRC749wJk8AOucgBzmhDSvU,105
44
51
  slidge/db/alembic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
52
  slidge/db/alembic/env.py,sha256=hsBlRNs0zF5diSHGRSa8Fi3qRVQDA2rJdR41AEIdvxc,1642
@@ -50,6 +57,7 @@ slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py,s
50
57
  slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py,sha256=f8TFS28CXjGhvIn41UYMoHYeODfqhKfo4O7gk-JwA1E,1134
51
58
  slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py,sha256=CMVP2wFz6s7t57eWdSaGtck8BXzfVPJhHE5AoWi34tI,1359
52
59
  slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py,sha256=O5BY1vpbtuYT5j6i3EMuuJAf6loIYT1kco8c-c6TF5g,1391
60
+ slidge/db/alembic/versions/45c24cc73c91_add_bob.py,sha256=UjMySZ5LaInyPt0KbAxx0rF4GQhZh8CwBeqHtNPdG1c,1249
53
61
  slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py,sha256=cObfqUzqdNezIeJdHe7YKFwRwtelXk8y1PwZ75chXDc,1629
54
62
  slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py,sha256=g37po0ydp8ZmzJrE5oFV7GscnploxjCtPDpw28SqVGk,1429
55
63
  slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py,sha256=18tG8B03Kq8Qz_-mMd28Beed6jow8XNTtrz7gT5QY3g,1210
@@ -62,8 +70,8 @@ slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py,sha256=jjQmlRv6nqd
62
70
  slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py,sha256=8Ga3VFgKrzMs_-B8OPtfP-0rey_MFaDg-QGtSbaft3o,640
63
71
  slidge/db/avatar.py,sha256=FfRt2Vu11ZKD9F3x1_drawvUd-TDE3mp7SE3BZ9hOOg,6467
64
72
  slidge/db/meta.py,sha256=v1Jf-npZ28QwdGpsLQWLBHEbEP3-jnPrygRg05tJ_Iw,1831
65
- slidge/db/models.py,sha256=yO4hM0VE1cQdDqWiZU1YW5ZjzwSnHUTavkGbkAMEB9A,13297
66
- slidge/db/store.py,sha256=jBkjTVXIg_N558rEfaDWzQ7mnIYMp2ziTk0o9KRVioo,42071
73
+ slidge/db/models.py,sha256=bsZCEtBDkvwiZiJNyp0cqxLHphtCUBIGnOPIaaG9opc,13738
74
+ slidge/db/store.py,sha256=1p-wAgG4K_QUehnmqRz-zvmW_PbXYYVq5qYMViF0cNY,46432
67
75
  slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
68
76
  slidge/group/archive.py,sha256=xGPkdSk8-BT6t6lNVo1FEwiFVAttoxCma8Tsyk5r8Kg,5279
69
77
  slidge/group/bookmarks.py,sha256=_LDf7A7aWkwPH88v7c-mOp8VJs3gSFM1-uCqSb4ThO8,5825
@@ -73,6 +81,7 @@ slidge/main.py,sha256=8oND7xpR3eLw7b62fT61UhYlmNp_9gv3tNz2N3xR7-c,6232
73
81
  slidge/migration.py,sha256=4BJmPIRB56_WIhRTqBFIIBXuvnhhBjjOMl4CE7jY6oc,1541
74
82
  slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
83
  slidge/slixfix/__init__.py,sha256=7GevigEt68hwgwHqXcsFogN5jRXRHPeqR6kwODCH4hc,3055
84
+ slidge/slixfix/delivery_receipt.py,sha256=3bWdZH3-X3CZJXmnI_TpjkTUUK-EY4Ktm78lW0-40fc,1366
76
85
  slidge/slixfix/link_preview/__init__.py,sha256=TDPTSEH5FQxgGpQpQIde-D72AHg-6YVWG-tOj4KpKmU,290
77
86
  slidge/slixfix/link_preview/link_preview.py,sha256=9PgdfnoyVMHnXS0w5OFp0wz3ku96Ck-HtRXbVUlDi1U,448
78
87
  slidge/slixfix/link_preview/stanza.py,sha256=YAXoNw2MD0a3nzvldGKlvSemjUMbUEG23regzmj4Ntc,2664
@@ -110,11 +119,11 @@ slidge/util/__init__.py,sha256=BELovoTMPcPPGz3D48esBr8A4BRRHXTvavfgnArBgEc,301
110
119
  slidge/util/archive_msg.py,sha256=xXAR0BI5r3d6KKWjae9594izCOv6iI03z2WLuTecNw8,1724
111
120
  slidge/util/conf.py,sha256=1j2OnOsCBar1tOObErhXR5RC3Vl3faliOZ1U8J3My58,6613
112
121
  slidge/util/db.py,sha256=4LxZj8oBYgiSnyBUnF_ALjr0TblkfNQq_p28sCfkHMY,242
113
- slidge/util/test.py,sha256=S8Kp5uJlWYPvnw8HMHUPlbrvsqwdBLs9MI99svMfjLg,13832
114
- slidge/util/types.py,sha256=o_5rbwfL_3e73JPT1t9o3kyDpJscFHzn4_bt8i3LoSk,5386
115
- slidge/util/util.py,sha256=8JeE0QObNGQr_Tw4OFPwQSz_EB_zh_0t9IJmNNhW0ic,9114
116
- slidge-0.2.0a9.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
117
- slidge-0.2.0a9.dist-info/METADATA,sha256=UYbPeUa9y7-m4f1ulm4CFYAdKYoGbf53gC-n_lf6aoI,4962
118
- slidge-0.2.0a9.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
119
- slidge-0.2.0a9.dist-info/entry_points.txt,sha256=SNl72KSocF5plsu_67xyH6wVWfGTXQbzkQgXbLtzDrQ,47
120
- slidge-0.2.0a9.dist-info/RECORD,,
122
+ slidge/util/test.py,sha256=movqj7rxDPZG4RF46CN1z73PSYAHIc_LuudquGRwLVU,13909
123
+ slidge/util/types.py,sha256=R_xfS5mRL0XUJIoDpnaAkZlTOoLPerduXBFftaVwIAI,5489
124
+ slidge/util/util.py,sha256=DyJWO2pmE-RiB9Rsy6TUTcvB-BDlmLZBW4PELx4arFQ,9156
125
+ slidge-0.2.0a10.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
126
+ slidge-0.2.0a10.dist-info/METADATA,sha256=_sFwLHhxETI7mHO1Hoetd6FVtNVYpyHHnboPxJucnkU,5006
127
+ slidge-0.2.0a10.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
128
+ slidge-0.2.0a10.dist-info/entry_points.txt,sha256=SNl72KSocF5plsu_67xyH6wVWfGTXQbzkQgXbLtzDrQ,47
129
+ slidge-0.2.0a10.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- from .base import BaseGateway
2
-
3
- __all__ = ("BaseGateway",)
@@ -1,35 +0,0 @@
1
- from typing import TYPE_CHECKING
2
-
3
- from slixmpp import CoroutineCallback, Iq, StanzaPath
4
- from slixmpp.exceptions import XMPPError
5
-
6
- if TYPE_CHECKING:
7
- from .base import BaseGateway
8
-
9
-
10
- class MucAdmin:
11
- def __init__(self, xmpp: "BaseGateway"):
12
- self.xmpp = xmpp
13
- xmpp.register_handler(
14
- CoroutineCallback(
15
- "muc#admin",
16
- StanzaPath("iq@type=get/mucadmin_query"),
17
- self._handle_admin, # type: ignore
18
- )
19
- )
20
-
21
- async def _handle_admin(self, iq: Iq):
22
- muc = await self.xmpp.get_muc_from_stanza(iq)
23
-
24
- affiliation = iq["mucadmin_query"]["item"]["affiliation"]
25
-
26
- if not affiliation:
27
- raise XMPPError("bad-request")
28
-
29
- reply = iq.reply()
30
- reply.enable("mucadmin_query")
31
- async for participant in muc.get_participants():
32
- if not participant.affiliation == affiliation:
33
- continue
34
- reply["mucadmin_query"].append(participant.mucadmin_item())
35
- reply.send()