slidge 0.2.0a9__tar.gz → 0.2.0a10__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. {slidge-0.2.0a9 → slidge-0.2.0a10}/PKG-INFO +2 -1
  2. {slidge-0.2.0a9 → slidge-0.2.0a10}/pyproject.toml +2 -1
  3. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/__version__.py +1 -1
  4. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/adhoc.py +1 -1
  5. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/base.py +4 -4
  6. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/contact/roster.py +7 -0
  7. slidge-0.2.0a10/slidge/core/dispatcher/__init__.py +3 -0
  8. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher}/caps.py +6 -4
  9. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher}/disco.py +11 -17
  10. slidge-0.2.0a10/slidge/core/dispatcher/message/__init__.py +10 -0
  11. slidge-0.2.0a10/slidge/core/dispatcher/message/chat_state.py +40 -0
  12. slidge-0.2.0a10/slidge/core/dispatcher/message/marker.py +67 -0
  13. slidge-0.2.0a10/slidge/core/dispatcher/message/message.py +397 -0
  14. slidge-0.2.0a10/slidge/core/dispatcher/muc/__init__.py +12 -0
  15. slidge-0.2.0a10/slidge/core/dispatcher/muc/admin.py +98 -0
  16. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher/muc}/mam.py +26 -15
  17. slidge-0.2.0a10/slidge/core/dispatcher/muc/misc.py +118 -0
  18. slidge-0.2.0a10/slidge/core/dispatcher/muc/owner.py +96 -0
  19. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher/muc}/ping.py +10 -15
  20. slidge-0.2.0a10/slidge/core/dispatcher/presence.py +177 -0
  21. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher}/registration.py +23 -2
  22. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/core/dispatcher}/search.py +9 -14
  23. slidge-0.2.0a10/slidge/core/dispatcher/session_dispatcher.py +84 -0
  24. slidge-0.2.0a10/slidge/core/dispatcher/util.py +174 -0
  25. slidge-0.2.0a9/slidge/core/gateway/vcard_temp.py → slidge-0.2.0a10/slidge/core/dispatcher/vcard.py +26 -12
  26. slidge-0.2.0a9/slidge/core/gateway/base.py → slidge-0.2.0a10/slidge/core/gateway.py +42 -137
  27. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/base.py +2 -2
  28. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/message.py +10 -4
  29. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/pubsub.py +2 -1
  30. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/session.py +28 -2
  31. slidge-0.2.0a10/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +42 -0
  32. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/models.py +13 -0
  33. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/store.py +128 -2
  34. {slidge-0.2.0a9/slidge/core/gateway → slidge-0.2.0a10/slidge/slixfix}/delivery_receipt.py +1 -1
  35. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/test.py +5 -1
  36. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/types.py +6 -0
  37. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/util.py +5 -2
  38. slidge-0.2.0a9/slidge/core/gateway/__init__.py +0 -3
  39. slidge-0.2.0a9/slidge/core/gateway/muc_admin.py +0 -35
  40. slidge-0.2.0a9/slidge/core/gateway/presence.py +0 -95
  41. slidge-0.2.0a9/slidge/core/gateway/session_dispatcher.py +0 -895
  42. {slidge-0.2.0a9 → slidge-0.2.0a10}/LICENSE +0 -0
  43. {slidge-0.2.0a9 → slidge-0.2.0a10}/README.md +0 -0
  44. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/__init__.py +0 -0
  45. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/__main__.py +0 -0
  46. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/__init__.py +0 -0
  47. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/admin.py +0 -0
  48. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/categories.py +0 -0
  49. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/chat_command.py +0 -0
  50. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/register.py +0 -0
  51. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/command/user.py +0 -0
  52. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/contact/__init__.py +0 -0
  53. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/contact/contact.py +0 -0
  54. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/__init__.py +0 -0
  55. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/config.py +0 -0
  56. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/__init__.py +0 -0
  57. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/attachment.py +0 -0
  58. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/avatar.py +0 -0
  59. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/db.py +0 -0
  60. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/disco.py +0 -0
  61. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/lock.py +0 -0
  62. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/message_maker.py +0 -0
  63. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/presence.py +0 -0
  64. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/core/mixins/recipient.py +0 -0
  65. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/__init__.py +0 -0
  66. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/__init__.py +0 -0
  67. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/env.py +0 -0
  68. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/old_user_store.py +0 -0
  69. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/script.py.mako +0 -0
  70. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
  71. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
  72. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
  73. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
  74. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
  75. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
  76. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
  77. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
  78. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
  79. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
  80. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
  81. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
  82. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
  83. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
  84. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
  85. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/avatar.py +0 -0
  86. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/db/meta.py +0 -0
  87. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/group/__init__.py +0 -0
  88. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/group/archive.py +0 -0
  89. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/group/bookmarks.py +0 -0
  90. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/group/participant.py +0 -0
  91. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/group/room.py +0 -0
  92. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/main.py +0 -0
  93. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/migration.py +0 -0
  94. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/py.typed +0 -0
  95. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/__init__.py +0 -0
  96. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/link_preview/__init__.py +0 -0
  97. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/link_preview/link_preview.py +0 -0
  98. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/link_preview/stanza.py +0 -0
  99. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/roster.py +0 -0
  100. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0077/__init__.py +0 -0
  101. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0077/register.py +0 -0
  102. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0077/stanza.py +0 -0
  103. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0100/__init__.py +0 -0
  104. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0100/gateway.py +0 -0
  105. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0100/stanza.py +0 -0
  106. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0153/__init__.py +0 -0
  107. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0153/stanza.py +0 -0
  108. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
  109. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0264/__init__.py +0 -0
  110. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0264/stanza.py +0 -0
  111. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0264/thumbnail.py +0 -0
  112. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0292/__init__.py +0 -0
  113. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0292/vcard4.py +0 -0
  114. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0313/__init__.py +0 -0
  115. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0313/mam.py +0 -0
  116. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0313/stanza.py +0 -0
  117. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0317/__init__.py +0 -0
  118. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0317/hats.py +0 -0
  119. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0317/stanza.py +0 -0
  120. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0356_old/__init__.py +0 -0
  121. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0356_old/privilege.py +0 -0
  122. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0356_old/stanza.py +0 -0
  123. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0424/__init__.py +0 -0
  124. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0424/retraction.py +0 -0
  125. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0424/stanza.py +0 -0
  126. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0490/__init__.py +0 -0
  127. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0490/mds.py +0 -0
  128. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/slixfix/xep_0490/stanza.py +0 -0
  129. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/__init__.py +0 -0
  130. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/archive_msg.py +0 -0
  131. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/conf.py +0 -0
  132. {slidge-0.2.0a9 → slidge-0.2.0a10}/slidge/util/db.py +0 -0
@@ -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,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "slidge"
3
- version = "0.2.0alpha9"
3
+ version = "0.2.0alpha10"
4
4
  description = "XMPP bridging framework"
5
5
  authors = ["Nicolas Cedilnik <nicoco@nicoco.fr>"]
6
6
  readme = "README.md"
@@ -29,6 +29,7 @@ slixmpp = "^1.8.5"
29
29
  sqlalchemy = "^2.0.29"
30
30
  alembic = "^1.13.1"
31
31
  thumbhash = "^0.1.2"
32
+ defusedxml = "^0.7.1"
32
33
 
33
34
  [build-system]
34
35
  requires = ["poetry-core>=1.0.0"]
@@ -2,4 +2,4 @@ from slidge.util.util import get_version # noqa: F401
2
2
 
3
3
  # this is modified before publish, but if someone cloned from the repo,
4
4
  # it can help
5
- __version__ = "0.2.0alpha9"
5
+ __version__ = "0.2.0alpha10"
@@ -13,7 +13,7 @@ from . import Command, CommandResponseType, Confirmation, Form, TableResult
13
13
  from .base import FormField
14
14
 
15
15
  if TYPE_CHECKING:
16
- from ..core.gateway.base import BaseGateway
16
+ from ..core.gateway import BaseGateway
17
17
  from ..core.session import BaseSession
18
18
 
19
19
 
@@ -6,9 +6,9 @@ from typing import (
6
6
  Any,
7
7
  Awaitable,
8
8
  Callable,
9
- Collection,
10
9
  Iterable,
11
10
  Optional,
11
+ Sequence,
12
12
  Type,
13
13
  TypedDict,
14
14
  Union,
@@ -54,11 +54,11 @@ class TableResult:
54
54
  Structured data as the result of a command
55
55
  """
56
56
 
57
- fields: Collection["FormField"]
57
+ fields: Sequence["FormField"]
58
58
  """
59
59
  The 'columns names' of the table.
60
60
  """
61
- items: Collection[dict[str, Union[str, JID]]]
61
+ items: Sequence[dict[str, Union[str, JID]]]
62
62
  """
63
63
  The rows of the table. Each row is a dict where keys are the fields ``var``
64
64
  attribute.
@@ -149,7 +149,7 @@ class Form:
149
149
 
150
150
  title: str
151
151
  instructions: str
152
- fields: Collection["FormField"]
152
+ fields: Sequence["FormField"]
153
153
  handler: FormHandlerType
154
154
  handler_args: Iterable[Any] = field(default_factory=list)
155
155
  handler_kwargs: dict[str, Any] = field(default_factory=dict)
@@ -92,6 +92,13 @@ class LegacyRoster(
92
92
  stored = self.__store.get_by_jid(self.session.user_pk, contact_jid)
93
93
  return await self.__update_contact(stored, legacy_id, username)
94
94
 
95
+ def by_jid_only_if_exists(self, contact_jid: JID) -> LegacyContactType | None:
96
+ with self.__store.session():
97
+ stored = self.__store.get_by_jid(self.session.user_pk, contact_jid)
98
+ if stored is not None and stored.updated:
99
+ return self._contact_cls.from_store(self.session, stored)
100
+ return None
101
+
95
102
  async def by_legacy_id(
96
103
  self, legacy_id: LegacyUserIdType, *args, **kwargs
97
104
  ) -> LegacyContactType:
@@ -0,0 +1,3 @@
1
+ from .session_dispatcher import SessionDispatcher
2
+
3
+ __all__ = ("SessionDispatcher",)
@@ -5,17 +5,19 @@ from slixmpp import Presence
5
5
  from slixmpp.exceptions import XMPPError
6
6
  from slixmpp.xmlstream import StanzaBase
7
7
 
8
+ from .util import DispatcherMixin
9
+
8
10
  if TYPE_CHECKING:
9
- from .base import BaseGateway
11
+ from slidge.core.gateway import BaseGateway
10
12
 
11
13
 
12
- class Caps:
14
+ class CapsMixin(DispatcherMixin):
13
15
  def __init__(self, xmpp: "BaseGateway"):
14
- self.xmpp = xmpp
16
+ super().__init__(xmpp)
15
17
  xmpp.del_filter("out", xmpp.plugin["xep_0115"]._filter_add_caps)
16
18
  xmpp.add_filter("out", self._filter_add_caps) # type:ignore
17
19
 
18
- async def _filter_add_caps(self, stanza: StanzaBase):
20
+ async def _filter_add_caps(self, stanza: StanzaBase) -> StanzaBase:
19
21
  # we rolled our own "add caps on presences" filter because
20
22
  # there is too much magic happening in slixmpp
21
23
  # anyway, we probably want to roll our own "dynamic disco"/caps
@@ -5,13 +5,15 @@ from slixmpp.exceptions import XMPPError
5
5
  from slixmpp.plugins.xep_0030.stanza.items import DiscoItems
6
6
  from slixmpp.types import OptJid
7
7
 
8
+ from .util import DispatcherMixin
9
+
8
10
  if TYPE_CHECKING:
9
- from .base import BaseGateway
11
+ from slidge.core.gateway import BaseGateway
10
12
 
11
13
 
12
- class Disco:
14
+ class DiscoMixin(DispatcherMixin):
13
15
  def __init__(self, xmpp: "BaseGateway"):
14
- self.xmpp = xmpp
16
+ super().__init__(xmpp)
15
17
 
16
18
  xmpp.plugin["xep_0030"].set_node_handler(
17
19
  "get_info",
@@ -36,15 +38,11 @@ class Disco:
36
38
  if ifrom is None:
37
39
  raise XMPPError("subscription-required")
38
40
 
39
- user = self.xmpp.store.users.get(ifrom)
40
- if user is None:
41
- raise XMPPError("registration-required")
42
- session = self.xmpp.get_session_from_user(user)
43
- await session.wait_for_ready()
41
+ assert jid is not None
42
+ session = await self._get_session_from_jid(jid=ifrom)
44
43
 
45
44
  log.debug("Looking for entity: %s", jid)
46
45
 
47
- assert jid is not None
48
46
  entity = await session.get_contact_or_group_or_participant(jid)
49
47
 
50
48
  if entity is None:
@@ -61,16 +59,12 @@ class Disco:
61
59
  if jid != self.xmpp.boundjid.bare:
62
60
  return DiscoItems()
63
61
 
64
- user = self.xmpp.store.users.get(ifrom)
65
- if user is None:
66
- raise XMPPError("registration-required")
67
-
68
- session = self.xmpp.get_session_from_user(user)
69
- await session.wait_for_ready()
62
+ assert ifrom is not None
63
+ session = await self._get_session_from_jid(ifrom)
70
64
 
71
65
  d = DiscoItems()
72
- for muc in sorted(session.bookmarks, key=lambda m: m.name):
73
- d.add_item(muc.jid, name=muc.name)
66
+ for room in self.xmpp.store.rooms.get_all_jid_and_names(session.user_pk):
67
+ d.add_item(room.jid, name=room.name)
74
68
 
75
69
  return d
76
70
 
@@ -0,0 +1,10 @@
1
+ from .chat_state import ChatStateMixin
2
+ from .marker import MarkerMixin
3
+ from .message import MessageContentMixin
4
+
5
+
6
+ class MessageMixin(ChatStateMixin, MarkerMixin, MessageContentMixin):
7
+ pass
8
+
9
+
10
+ __all__ = ("MessageMixin",)
@@ -0,0 +1,40 @@
1
+ from slixmpp import Message
2
+ from slixmpp.xmlstream import StanzaBase
3
+
4
+ from ..util import DispatcherMixin, exceptions_to_xmpp_errors
5
+
6
+
7
+ class ChatStateMixin(DispatcherMixin):
8
+ def __init__(self, xmpp) -> None:
9
+ super().__init__(xmpp)
10
+ xmpp.add_event_handler("chatstate_active", self.on_chatstate_active)
11
+ xmpp.add_event_handler("chatstate_inactive", self.on_chatstate_inactive)
12
+ xmpp.add_event_handler("chatstate_composing", self.on_chatstate_composing)
13
+ xmpp.add_event_handler("chatstate_paused", self.on_chatstate_paused)
14
+
15
+ @exceptions_to_xmpp_errors
16
+ async def on_chatstate_active(self, msg: StanzaBase) -> None:
17
+ assert isinstance(msg, Message)
18
+ if msg["body"]:
19
+ # if there is a body, it's handled in on_legacy_message()
20
+ return
21
+ session, entity, thread = await self._get_session_entity_thread(msg)
22
+ await session.on_active(entity, thread)
23
+
24
+ @exceptions_to_xmpp_errors
25
+ async def on_chatstate_inactive(self, msg: StanzaBase) -> None:
26
+ assert isinstance(msg, Message)
27
+ session, entity, thread = await self._get_session_entity_thread(msg)
28
+ await session.on_inactive(entity, thread)
29
+
30
+ @exceptions_to_xmpp_errors
31
+ async def on_chatstate_composing(self, msg: StanzaBase) -> None:
32
+ assert isinstance(msg, Message)
33
+ session, entity, thread = await self._get_session_entity_thread(msg)
34
+ await session.on_composing(entity, thread)
35
+
36
+ @exceptions_to_xmpp_errors
37
+ async def on_chatstate_paused(self, msg: StanzaBase) -> None:
38
+ assert isinstance(msg, Message)
39
+ session, entity, thread = await self._get_session_entity_thread(msg)
40
+ await session.on_paused(entity, thread)
@@ -0,0 +1,67 @@
1
+ from slixmpp import JID, Message
2
+ from slixmpp.xmlstream import StanzaBase
3
+
4
+ from ....group.room import LegacyMUC
5
+ from ....util.types import Recipient
6
+ from ..util import (
7
+ DispatcherMixin,
8
+ _get_entity,
9
+ _xmpp_to_legacy_thread,
10
+ exceptions_to_xmpp_errors,
11
+ )
12
+
13
+
14
+ class MarkerMixin(DispatcherMixin):
15
+ def __init__(self, xmpp) -> None:
16
+ super().__init__(xmpp)
17
+ xmpp.add_event_handler("marker_displayed", self.on_marker_displayed)
18
+ xmpp.add_event_handler(
19
+ "message_displayed_synchronization_publish",
20
+ self.on_message_displayed_synchronization_publish,
21
+ )
22
+
23
+ @exceptions_to_xmpp_errors
24
+ async def on_marker_displayed(self, msg: StanzaBase) -> None:
25
+ assert isinstance(msg, Message)
26
+ session = await self._get_session(msg)
27
+
28
+ e: Recipient = await _get_entity(session, msg)
29
+ legacy_thread = await _xmpp_to_legacy_thread(session, msg, e)
30
+ displayed_msg_id = msg["displayed"]["id"]
31
+ if not isinstance(e, LegacyMUC) and self.xmpp.MARK_ALL_MESSAGES:
32
+ to_mark = e.get_msg_xmpp_id_up_to(displayed_msg_id) # type: ignore
33
+ if to_mark is None:
34
+ session.log.debug("Can't mark all messages up to %s", displayed_msg_id)
35
+ to_mark = [displayed_msg_id]
36
+ else:
37
+ to_mark = [displayed_msg_id]
38
+ for xmpp_id in to_mark:
39
+ await session.on_displayed(
40
+ e, self._xmpp_msg_id_to_legacy(session, xmpp_id), legacy_thread
41
+ )
42
+ if isinstance(e, LegacyMUC):
43
+ await e.echo(msg, None)
44
+
45
+ @exceptions_to_xmpp_errors
46
+ async def on_message_displayed_synchronization_publish(
47
+ self, msg: StanzaBase
48
+ ) -> None:
49
+ assert isinstance(msg, Message)
50
+ chat_jid = JID(msg["pubsub_event"]["items"]["item"]["id"])
51
+ if chat_jid.server != self.xmpp.boundjid.bare:
52
+ return
53
+
54
+ session = await self._get_session(msg, timeout=None)
55
+
56
+ if chat_jid == self.xmpp.boundjid.bare:
57
+ return
58
+
59
+ chat = await session.get_contact_or_group_or_participant(chat_jid)
60
+ if not isinstance(chat, LegacyMUC):
61
+ session.log.debug("Ignoring non-groupchat MDS event")
62
+ return
63
+
64
+ stanza_id = msg["pubsub_event"]["items"]["item"]["displayed"]["stanza_id"]["id"]
65
+ await session.on_displayed(
66
+ chat, self._xmpp_msg_id_to_legacy(session, stanza_id)
67
+ )