slidge 0.2.0b1__tar.gz → 0.2.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. {slidge-0.2.0b1 → slidge-0.2.2}/PKG-INFO +1 -1
  2. {slidge-0.2.0b1 → slidge-0.2.2}/pyproject.toml +1 -1
  3. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/__version__.py +1 -1
  4. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/base.py +1 -1
  5. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/chat_command.py +5 -2
  6. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/register.py +3 -2
  7. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/user.py +1 -1
  8. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/contact/contact.py +3 -3
  9. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/contact/roster.py +3 -3
  10. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/presence.py +4 -5
  11. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/session_dispatcher.py +2 -2
  12. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/gateway.py +6 -3
  13. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/attachment.py +14 -3
  14. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/message.py +1 -1
  15. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/models.py +7 -1
  16. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/group/room.py +2 -2
  17. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/main.py +1 -1
  18. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/__init__.py +29 -32
  19. {slidge-0.2.0b1 → slidge-0.2.2}/LICENSE +0 -0
  20. {slidge-0.2.0b1 → slidge-0.2.2}/README.md +0 -0
  21. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/__init__.py +0 -0
  22. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/__main__.py +0 -0
  23. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/__init__.py +0 -0
  24. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/adhoc.py +0 -0
  25. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/admin.py +0 -0
  26. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/command/categories.py +0 -0
  27. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/contact/__init__.py +0 -0
  28. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/__init__.py +0 -0
  29. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/config.py +0 -0
  30. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/__init__.py +0 -0
  31. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/caps.py +0 -0
  32. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/disco.py +0 -0
  33. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/message/__init__.py +0 -0
  34. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/message/chat_state.py +0 -0
  35. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/message/marker.py +0 -0
  36. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/message/message.py +0 -0
  37. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/__init__.py +0 -0
  38. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/admin.py +0 -0
  39. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/mam.py +0 -0
  40. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/misc.py +0 -0
  41. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/owner.py +0 -0
  42. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/muc/ping.py +0 -0
  43. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/registration.py +0 -0
  44. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/search.py +0 -0
  45. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/util.py +0 -0
  46. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/dispatcher/vcard.py +0 -0
  47. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/__init__.py +0 -0
  48. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/avatar.py +0 -0
  49. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/base.py +0 -0
  50. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/db.py +0 -0
  51. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/disco.py +0 -0
  52. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/lock.py +0 -0
  53. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/message_maker.py +0 -0
  54. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/message_text.py +0 -0
  55. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/presence.py +0 -0
  56. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/mixins/recipient.py +0 -0
  57. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/pubsub.py +0 -0
  58. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/core/session.py +0 -0
  59. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/__init__.py +0 -0
  60. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/__init__.py +0 -0
  61. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/env.py +0 -0
  62. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/old_user_store.py +0 -0
  63. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/script.py.mako +0 -0
  64. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
  65. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -0
  66. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
  67. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
  68. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
  69. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
  70. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -0
  71. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
  72. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
  73. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
  74. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
  75. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
  76. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
  77. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
  78. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
  79. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
  80. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
  81. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/avatar.py +0 -0
  82. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/meta.py +0 -0
  83. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/db/store.py +0 -0
  84. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/group/__init__.py +0 -0
  85. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/group/archive.py +0 -0
  86. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/group/bookmarks.py +0 -0
  87. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/group/participant.py +0 -0
  88. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/migration.py +0 -0
  89. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/py.typed +0 -0
  90. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/delivery_receipt.py +0 -0
  91. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/link_preview/__init__.py +0 -0
  92. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/link_preview/link_preview.py +0 -0
  93. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/link_preview/stanza.py +0 -0
  94. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/roster.py +0 -0
  95. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0077/__init__.py +0 -0
  96. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0077/register.py +0 -0
  97. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0077/stanza.py +0 -0
  98. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0100/__init__.py +0 -0
  99. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0100/gateway.py +0 -0
  100. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0100/stanza.py +0 -0
  101. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0153/__init__.py +0 -0
  102. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0153/stanza.py +0 -0
  103. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
  104. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0264/__init__.py +0 -0
  105. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0264/stanza.py +0 -0
  106. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0264/thumbnail.py +0 -0
  107. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0292/__init__.py +0 -0
  108. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0292/vcard4.py +0 -0
  109. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0313/__init__.py +0 -0
  110. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0313/mam.py +0 -0
  111. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0313/stanza.py +0 -0
  112. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0317/__init__.py +0 -0
  113. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0317/hats.py +0 -0
  114. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0317/stanza.py +0 -0
  115. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0356_old/__init__.py +0 -0
  116. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0356_old/privilege.py +0 -0
  117. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0356_old/stanza.py +0 -0
  118. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0424/__init__.py +0 -0
  119. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0424/retraction.py +0 -0
  120. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0424/stanza.py +0 -0
  121. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0490/__init__.py +0 -0
  122. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0490/mds.py +0 -0
  123. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/slixfix/xep_0490/stanza.py +0 -0
  124. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/__init__.py +0 -0
  125. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/archive_msg.py +0 -0
  126. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/conf.py +0 -0
  127. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/db.py +0 -0
  128. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/test.py +0 -0
  129. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/types.py +0 -0
  130. {slidge-0.2.0b1 → slidge-0.2.2}/slidge/util/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slidge
3
- Version: 0.2.0b1
3
+ Version: 0.2.2
4
4
  Summary: XMPP bridging framework
5
5
  Home-page: https://sr.ht/~nicoco/slidge/
6
6
  License: AGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "slidge"
3
- version = "0.2.0beta1"
3
+ version = "0.2.2"
4
4
  description = "XMPP bridging framework"
5
5
  authors = ["Nicolas Cedilnik <nicoco@nicoco.fr>"]
6
6
  readme = "README.md"
@@ -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.0beta1"
5
+ __version__ = "0.2.2"
@@ -245,7 +245,7 @@ class FormField:
245
245
  self.type = "text-private"
246
246
 
247
247
  def __acceptable_options(self) -> list[str]:
248
- if not self.options:
248
+ if self.options is None:
249
249
  raise RuntimeError
250
250
  return [x["value"] for x in self.options]
251
251
 
@@ -175,7 +175,9 @@ class ChatCommandProvider:
175
175
  else:
176
176
  if f.type == "list-multi":
177
177
  msg.reply(
178
- "Multiple selection allowed, use a single space as a separator"
178
+ "Multiple selection allowed, use new lines as a separator, ie, "
179
+ "one selected item per line. To select no item, reply with a space "
180
+ "(the punctuation)."
179
181
  ).send()
180
182
  if f.options:
181
183
  for o in f.options:
@@ -202,7 +204,8 @@ class ChatCommandProvider:
202
204
  ans = "false"
203
205
 
204
206
  if f.type.endswith("multi"):
205
- form_values[f.var] = f.validate(ans.split(" "))
207
+ choices = [] if ans == " " else ans.split("\n")
208
+ form_values[f.var] = f.validate(choices)
206
209
  else:
207
210
  form_values[f.var] = f.validate(ans)
208
211
  result = await self.__wrap_handler(
@@ -75,7 +75,8 @@ class Register(Command):
75
75
  self.xmpp.event("user_register", Iq(sfrom=ifrom.bare))
76
76
  return self.SUCCESS_MESSAGE
77
77
 
78
- async def run(self, _session, _ifrom, *_):
78
+ async def run(self, _session, ifrom: JID, *_):
79
+ self.xmpp.raise_if_not_allowed_jid(ifrom)
79
80
  return Form(
80
81
  title=f"Registration to '{self.xmpp.COMPONENT_NAME}'",
81
82
  instructions=self.xmpp.REGISTRATION_INSTRUCTIONS,
@@ -97,7 +98,7 @@ class Register(Command):
97
98
  raise
98
99
 
99
100
  user = GatewayUser(
100
- jid=ifrom.bare,
101
+ jid=JID(ifrom.bare),
101
102
  legacy_module_data=form_values if data is None else data,
102
103
  )
103
104
 
@@ -292,7 +292,7 @@ class Unregister(Command):
292
292
  user = self.xmpp.store.users.get(session.user_jid)
293
293
  assert user is not None
294
294
  await self.xmpp.unregister_user(user)
295
- return "OK"
295
+ return "You are not registered anymore. Bye!"
296
296
 
297
297
 
298
298
  class LeaveGroup(Command):
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Generic, Iterable, Optional, Self, Union
6
6
  from xml.etree import ElementTree as ET
7
7
 
8
8
  from slixmpp import JID, Message, Presence
9
- from slixmpp.exceptions import IqError
9
+ from slixmpp.exceptions import IqError, IqTimeout
10
10
  from slixmpp.plugins.xep_0292.stanza import VCard4
11
11
  from slixmpp.types import MessageTypes
12
12
 
@@ -454,7 +454,7 @@ class LegacyContact(
454
454
  except PermissionError:
455
455
  warnings.warn(
456
456
  "Slidge does not have privileges to add contacts to the roster. Refer"
457
- " to https://slidge.readthedocs.io/en/latest/admin/xmpp_server.html for"
457
+ " to https://slidge.im/core/admin/privilege.html for"
458
458
  " more info."
459
459
  )
460
460
  if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
@@ -463,7 +463,7 @@ class LegacyContact(
463
463
  "slidge is not allowed to manage your roster."
464
464
  )
465
465
  return
466
- except IqError as e:
466
+ except (IqError, IqTimeout) as e:
467
467
  self.log.warning("Could not add to roster", exc_info=e)
468
468
  else:
469
469
  # we only broadcast pubsub events for contacts added to the roster
@@ -4,7 +4,7 @@ import warnings
4
4
  from typing import TYPE_CHECKING, AsyncIterator, Generic, Iterator, Optional, Type
5
5
 
6
6
  from slixmpp import JID
7
- from slixmpp.exceptions import IqError, XMPPError
7
+ from slixmpp.exceptions import IqError, IqTimeout, XMPPError
8
8
  from slixmpp.jid import JID_UNESCAPE_TRANSFORMATIONS, _unescape_node
9
9
 
10
10
  from ..core.mixins.lock import NamedLockMixin
@@ -210,7 +210,7 @@ class LegacyRoster(
210
210
  self.session.user_jid.bare
211
211
  )
212
212
  user_roster = iq["roster"]["items"]
213
- except (PermissionError, IqError):
213
+ except (PermissionError, IqError, IqTimeout):
214
214
  user_roster = None
215
215
 
216
216
  with self.__store.session() as orm:
@@ -232,7 +232,7 @@ class LegacyRoster(
232
232
  self.session.user_jid.bare,
233
233
  item,
234
234
  )
235
- except (PermissionError, IqError) as e:
235
+ except (PermissionError, IqError, IqTimeout) as e:
236
236
  warnings.warn(f"Could not add to roster: {e}")
237
237
  else:
238
238
  contact._added_to_roster = True
@@ -154,14 +154,13 @@ class PresenceHandlerMixin(DispatcherMixin):
154
154
  # when setting a status message, or going away, etc.
155
155
  return
156
156
 
157
- # We can't use XMPPError here because from must be room@slidge/VALID-USER-NICK
157
+ # We can't use XMPPError here because XMPPError does not have a way to
158
+ # add the <x xmlns="http://jabber.org/protocol/muc" /> element
158
159
 
159
- error_from = JID(muc.jid)
160
- error_from.resource = muc.user_nick
161
160
  error_stanza = p.error()
162
161
  error_stanza.set_to(p.get_from())
163
- error_stanza.set_from(error_from)
164
- error_stanza.enable("muc_join")
162
+ error_stanza.set_from(pto)
163
+ error_stanza.enable("muc_join") # <x xmlns="http://jabber.org/protocol/muc" />
165
164
  error_stanza.enable("error")
166
165
  error_stanza["error"]["type"] = "cancel"
167
166
  error_stanza["error"]["by"] = muc.jid
@@ -2,7 +2,7 @@ import logging
2
2
  from typing import TYPE_CHECKING
3
3
 
4
4
  from slixmpp import Message
5
- from slixmpp.exceptions import IqError
5
+ from slixmpp.exceptions import IqError, IqTimeout
6
6
  from slixmpp.plugins.xep_0084.stanza import Info
7
7
 
8
8
  from ..session import BaseSession
@@ -59,7 +59,7 @@ class SessionDispatcher(
59
59
  iq = await self.xmpp.plugin["xep_0084"].retrieve_avatar(
60
60
  session.user_jid, hash_, ifrom=self.xmpp.boundjid.bare
61
61
  )
62
- except IqError as e:
62
+ except (IqError, IqTimeout) as e:
63
63
  session.log.warning("Could not fetch the user's avatar: %s", e)
64
64
  return
65
65
  bytes_ = iq["pubsub"]["items"]["item"]["avatar_data"]["value"]
@@ -429,7 +429,7 @@ class BaseGateway(
429
429
  try:
430
430
  await self["xep_0100"].add_component_to_roster(user.jid)
431
431
  await self.__add_component_to_mds_whitelist(user.jid)
432
- except IqError as e:
432
+ except (IqError, IqTimeout) as e:
433
433
  # TODO: remove the user when this happens? or at least
434
434
  # this can happen when the user has unsubscribed from the XMPP server
435
435
  log.warning(
@@ -464,7 +464,7 @@ class BaseGateway(
464
464
  "create the MDS node of %s",
465
465
  user_jid,
466
466
  )
467
- except IqError as e:
467
+ except (IqError, IqTimeout) as e:
468
468
  # conflict this means the node already exists, we can ignore that
469
469
  if e.condition != "conflict":
470
470
  log.exception(
@@ -548,7 +548,7 @@ class BaseGateway(
548
548
  self.xmpp.plugin["xep_0084"].stanza.MetaData.namespace,
549
549
  ifrom=self.boundjid.bare,
550
550
  )
551
- except IqError:
551
+ except (IqError, IqTimeout):
552
552
  self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
553
553
  return
554
554
  await self.__dispatcher.on_avatar_metadata_info(
@@ -797,6 +797,9 @@ class BaseGateway(
797
797
  fut.set_exception(exception)
798
798
 
799
799
  async def unregister_user(self, user: GatewayUser):
800
+ self.send_presence(
801
+ pshow="busy", pstatus="You are not registered to this gateway anymore."
802
+ )
800
803
  await self.xmpp.plugin["xep_0077"].api["user_remove"](None, None, user.jid)
801
804
  await self.xmpp.session_cls.kill_by_jid(user.jid)
802
805
 
@@ -19,7 +19,7 @@ from xml.etree import ElementTree as ET
19
19
  import thumbhash
20
20
  from PIL import Image, ImageOps
21
21
  from slixmpp import JID, Message
22
- from slixmpp.exceptions import IqError
22
+ from slixmpp.exceptions import IqError, IqTimeout
23
23
  from slixmpp.plugins.xep_0363 import FileUploadError
24
24
  from slixmpp.plugins.xep_0447.stanza import StatelessFileSharing
25
25
 
@@ -65,7 +65,7 @@ class AttachmentMixin(TextMessageMixin):
65
65
  ifrom=config.UPLOAD_REQUESTER or self.xmpp.boundjid,
66
66
  domain=JID(domain),
67
67
  )
68
- except (FileUploadError, IqError) as e:
68
+ except (FileUploadError, IqError, IqTimeout) as e:
69
69
  warnings.warn(f"Something is wrong with the upload service: {e!r}")
70
70
  return None
71
71
  finally:
@@ -374,9 +374,20 @@ class AttachmentMixin(TextMessageMixin):
374
374
  if xmpp_id == original_xmpp_id:
375
375
  continue
376
376
  self.retract(xmpp_id, thread)
377
+
378
+ if reply_to is not None and reply_to.body:
379
+ # We cannot have a "quote fallback" for attachments since most (all?)
380
+ # XMPP clients will only treat a message as an attachment if the
381
+ # body is the URL and nothing else.
382
+ reply_to_for_attachment: MessageReference | None = MessageReference(
383
+ reply_to.legacy_id, reply_to.author
384
+ )
385
+ else:
386
+ reply_to_for_attachment = reply_to
387
+
377
388
  msg = self._make_message(
378
389
  when=when,
379
- reply_to=reply_to,
390
+ reply_to=reply_to_for_attachment,
380
391
  carbon=carbon,
381
392
  mto=mto,
382
393
  thread=thread,
@@ -172,7 +172,7 @@ class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
172
172
  warnings.warn(
173
173
  "Slidge does not have privileges to send message on behalf of"
174
174
  " user.Refer to"
175
- " https://slidge.readthedocs.io/en/latest/admin/xmpp_server.html"
175
+ " https://slidge.im/core/admin/privilege.html"
176
176
  " for more info."
177
177
  )
178
178
 
@@ -235,11 +235,17 @@ class Room(Base):
235
235
  updated: Mapped[bool] = mapped_column(default=False)
236
236
 
237
237
  participants: Mapped[list["Participant"]] = relationship(
238
- back_populates="room", primaryjoin="Participant.room_id == Room.id"
238
+ back_populates="room",
239
+ primaryjoin="Participant.room_id == Room.id",
240
+ cascade="all, delete-orphan",
239
241
  )
240
242
 
241
243
  avatar_legacy_id: Mapped[Optional[str]] = mapped_column(nullable=True)
242
244
 
245
+ archive: Mapped[list["ArchivedMessage"]] = relationship(
246
+ cascade="all, delete-orphan"
247
+ )
248
+
243
249
 
244
250
  class ArchivedMessage(Base):
245
251
  """
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, AsyncIterator, Generic, Optional, Self, Union
9
9
  from uuid import uuid4
10
10
 
11
11
  from slixmpp import JID, Iq, Message, Presence
12
- from slixmpp.exceptions import IqError, XMPPError
12
+ from slixmpp.exceptions import IqError, IqTimeout, XMPPError
13
13
  from slixmpp.jid import _unescape_node
14
14
  from slixmpp.plugins.xep_0004 import Form
15
15
  from slixmpp.plugins.xep_0060.stanza import Item
@@ -1029,7 +1029,7 @@ class LegacyMUC(
1029
1029
  # (slixmpp annoying magic)
1030
1030
  item = ans["pubsub"]["items"]["item"]
1031
1031
  item["id"] = self.jid
1032
- except IqError:
1032
+ except (IqError, IqTimeout):
1033
1033
  item["conference"]["autojoin"] = auto_join
1034
1034
  except PermissionError:
1035
1035
  warnings.warn(
@@ -112,7 +112,7 @@ def configure():
112
112
 
113
113
  if not (h := config.HOME_DIR).exists():
114
114
  logging.info("Creating directory '%s'", h)
115
- h.mkdir()
115
+ os.makedirs(h)
116
116
 
117
117
  config.UPLOAD_REQUESTER = config.UPLOAD_REQUESTER or config.JID.bare
118
118
 
@@ -1,12 +1,13 @@
1
1
  # This module contains patches for slixmpp; some have pending requests upstream
2
2
  # and should be removed on the next slixmpp release.
3
- import logging
4
- from collections import defaultdict
3
+
4
+ # ruff: noqa: F401
5
5
 
6
6
  import slixmpp.plugins
7
- from slixmpp import Message
7
+ from slixmpp import Iq, Message
8
+ from slixmpp.exceptions import XMPPError
8
9
  from slixmpp.plugins.xep_0050 import XEP_0050, Command
9
- from slixmpp.plugins.xep_0356.privilege import _VALID_ACCESSES, XEP_0356
10
+ from slixmpp.plugins.xep_0231 import XEP_0231
10
11
  from slixmpp.xmlstream import StanzaBase
11
12
 
12
13
  from . import ( # xep_0356,
@@ -23,36 +24,33 @@ from . import ( # xep_0356,
23
24
  xep_0490,
24
25
  )
25
26
 
26
- # ruff: noqa: F401
27
27
 
28
+ async def _handle_bob_iq(self, iq: Iq):
29
+ cid = iq["bob"]["cid"]
28
30
 
29
- # TODO: Remove me once https://codeberg.org/poezio/slixmpp/pulls/3541 makes it
30
- # to a slixmpp release
31
- def _handle_privilege(self, msg: StanzaBase):
32
- """
33
- Called when the XMPP server advertise the component's privileges.
31
+ if iq["type"] == "result":
32
+ await self.api["set_bob"](iq["from"], None, iq["to"], args=iq["bob"])
33
+ self.xmpp.event("bob", iq)
34
+ elif iq["type"] == "get":
35
+ data = await self.api["get_bob"](iq["to"], None, iq["from"], args=cid)
34
36
 
35
- Stores the privileges in this instance's granted_privileges attribute (a dict)
36
- and raises the privileges_advertised event
37
- """
38
- permissions = self.granted_privileges[msg.get_from()]
39
- for perm in msg["privilege"]["perms"]:
40
- access = perm["access"]
41
- if access == "iq":
42
- if not perm.get_plugin("namespace", check=True):
43
- permissions.iq = defaultdict(lambda: perm["type"])
44
- else:
45
- for ns in perm["namespaces"]:
46
- permissions.iq[ns["ns"]] = ns["type"]
47
- elif access in _VALID_ACCESSES:
48
- setattr(permissions, access, perm["type"])
49
- else:
50
- log.warning("Received an invalid privileged access: %s", access)
51
- log.debug("Privileges: %s", self.granted_privileges)
52
- self.xmpp.event("privileges_advertised")
53
-
54
-
55
- XEP_0356._handle_privilege = _handle_privilege
37
+ if data is None:
38
+ raise XMPPError(
39
+ "item-not-found",
40
+ f"Bits of binary '{cid}' is not available.",
41
+ )
42
+
43
+ if isinstance(data, Iq):
44
+ data["id"] = iq["id"]
45
+ data.send()
46
+ return
47
+
48
+ iq = iq.reply()
49
+ iq.append(data)
50
+ iq.send()
51
+
52
+
53
+ XEP_0231._handle_bob_iq = _handle_bob_iq
56
54
 
57
55
 
58
56
  def session_bind(self, jid):
@@ -98,4 +96,3 @@ slixmpp.plugins.PLUGINS.extend(
98
96
 
99
97
 
100
98
  Message.reply = reply # type: ignore
101
- log = logging.getLogger(__name__)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes