slidge 0.3.0b2__tar.gz → 0.3.0b3__tar.gz

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.
Files changed (186) hide show
  1. {slidge-0.3.0b2 → slidge-0.3.0b3}/PKG-INFO +1 -1
  2. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/examples/ejabberd.yaml +5 -0
  3. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/privilege.rst +6 -6
  4. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/attachment.py +4 -0
  5. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/base.py +1 -1
  6. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/disco.py +1 -1
  7. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/store.py +1 -1
  8. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/group/bookmarks.py +21 -3
  9. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/group/room.py +37 -10
  10. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/types.py +2 -0
  11. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/PKG-INFO +1 -1
  12. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_attachment.py +22 -9
  13. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_muc.py +1 -3
  14. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_session_2.py +80 -2
  15. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_shakespeare.py +1 -2
  16. {slidge-0.3.0b2 → slidge-0.3.0b3}/.gitignore +0 -0
  17. {slidge-0.3.0b2 → slidge-0.3.0b3}/.pre-commit-config.yaml +0 -0
  18. {slidge-0.3.0b2 → slidge-0.3.0b3}/.woodpecker/container-ci.yaml +0 -0
  19. {slidge-0.3.0b2 → slidge-0.3.0b3}/.woodpecker/docs.yaml +0 -0
  20. {slidge-0.3.0b2 → slidge-0.3.0b3}/.woodpecker/package.yaml +0 -0
  21. {slidge-0.3.0b2 → slidge-0.3.0b3}/.woodpecker/test.yaml +0 -0
  22. {slidge-0.3.0b2 → slidge-0.3.0b3}/Dockerfile +0 -0
  23. {slidge-0.3.0b2 → slidge-0.3.0b3}/LICENSE +0 -0
  24. {slidge-0.3.0b2 → slidge-0.3.0b3}/README.md +0 -0
  25. {slidge-0.3.0b2 → slidge-0.3.0b3}/commitlint.config.js +0 -0
  26. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/5x5.png +0 -0
  27. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/slidge-color-small.png +0 -0
  28. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/slidge-color.png +0 -0
  29. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/slidge-mono-black.png +0 -0
  30. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/slidge-mono-white.png +0 -0
  31. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/assets/slidge.svg +0 -0
  32. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/confs/movim.env +0 -0
  33. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/confs/nginx.conf +0 -0
  34. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/confs/slidge-dev.ini +0 -0
  35. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/confs/slidge-example.ini +0 -0
  36. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/hot-reload.sh +0 -0
  37. {slidge-0.3.0b2 → slidge-0.3.0b3}/dev/prettify_tests.py +0 -0
  38. {slidge-0.3.0b2 → slidge-0.3.0b3}/doap.xml +0 -0
  39. {slidge-0.3.0b2 → slidge-0.3.0b3}/docker-compose.yml +0 -0
  40. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/Makefile +0 -0
  41. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/attachments.rst +0 -0
  42. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/component.rst +0 -0
  43. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/config/index.rst +0 -0
  44. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/daemon.rst +0 -0
  45. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/examples/index.rst +0 -0
  46. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/examples/prosody.cfg.lua +0 -0
  47. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/index.rst +0 -0
  48. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/install.rst +0 -0
  49. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/admin/note.rst +0 -0
  50. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/codeberg.svg +0 -0
  51. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/conf.py +0 -0
  52. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/dev/contributing.rst +0 -0
  53. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/dev/design.rst +0 -0
  54. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/dev/howto.rst +0 -0
  55. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/dev/index.rst +0 -0
  56. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/dev/tutorial.rst +0 -0
  57. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/glossary.rst +0 -0
  58. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/index.rst +0 -0
  59. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/commands.rst +0 -0
  60. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/contacts.rst +0 -0
  61. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/foxyproxy.png +0 -0
  62. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/gajim.png +0 -0
  63. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/index.rst +0 -0
  64. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/low_profile.rst +0 -0
  65. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/movim1.png +0 -0
  66. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/movim2.png +0 -0
  67. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/note.rst +0 -0
  68. {slidge-0.3.0b2 → slidge-0.3.0b3}/docs/source/user/register.rst +0 -0
  69. {slidge-0.3.0b2 → slidge-0.3.0b3}/pyproject.toml +0 -0
  70. {slidge-0.3.0b2 → slidge-0.3.0b3}/setup.cfg +0 -0
  71. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/__init__.py +0 -0
  72. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/__main__.py +0 -0
  73. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/__init__.py +0 -0
  74. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/adhoc.py +0 -0
  75. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/admin.py +0 -0
  76. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/base.py +0 -0
  77. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/categories.py +0 -0
  78. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/chat_command.py +0 -0
  79. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/register.py +0 -0
  80. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/command/user.py +0 -0
  81. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/contact/__init__.py +0 -0
  82. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/contact/contact.py +0 -0
  83. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/contact/roster.py +0 -0
  84. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/__init__.py +0 -0
  85. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/config.py +0 -0
  86. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/__init__.py +0 -0
  87. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/caps.py +0 -0
  88. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/disco.py +0 -0
  89. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/message/__init__.py +0 -0
  90. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/message/chat_state.py +0 -0
  91. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/message/marker.py +0 -0
  92. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/message/message.py +0 -0
  93. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/__init__.py +0 -0
  94. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/admin.py +0 -0
  95. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/mam.py +0 -0
  96. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/misc.py +0 -0
  97. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/owner.py +0 -0
  98. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/muc/ping.py +0 -0
  99. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/presence.py +0 -0
  100. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/registration.py +0 -0
  101. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/search.py +0 -0
  102. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/session_dispatcher.py +0 -0
  103. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/util.py +0 -0
  104. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/dispatcher/vcard.py +0 -0
  105. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/gateway.py +0 -0
  106. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/__init__.py +0 -0
  107. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/avatar.py +0 -0
  108. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/db.py +0 -0
  109. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/message.py +0 -0
  110. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/message_maker.py +0 -0
  111. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/message_text.py +0 -0
  112. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/presence.py +0 -0
  113. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/mixins/recipient.py +0 -0
  114. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/pubsub.py +0 -0
  115. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/core/session.py +0 -0
  116. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/__init__.py +0 -0
  117. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/alembic/__init__.py +0 -0
  118. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/alembic/env.py +0 -0
  119. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/alembic/script.py.mako +0 -0
  120. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +0 -0
  121. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/avatar.py +0 -0
  122. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/meta.py +0 -0
  123. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/db/models.py +0 -0
  124. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/group/__init__.py +0 -0
  125. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/group/archive.py +0 -0
  126. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/group/participant.py +0 -0
  127. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/main.py +0 -0
  128. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/migration.py +0 -0
  129. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/py.typed +0 -0
  130. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/__init__.py +0 -0
  131. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/delivery_receipt.py +0 -0
  132. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/link_preview/__init__.py +0 -0
  133. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/link_preview/link_preview.py +0 -0
  134. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/link_preview/stanza.py +0 -0
  135. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/roster.py +0 -0
  136. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0077/__init__.py +0 -0
  137. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0077/register.py +0 -0
  138. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0077/stanza.py +0 -0
  139. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0100/__init__.py +0 -0
  140. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0100/gateway.py +0 -0
  141. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0100/stanza.py +0 -0
  142. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0153/__init__.py +0 -0
  143. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
  144. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0292/__init__.py +0 -0
  145. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/slixfix/xep_0292/vcard4.py +0 -0
  146. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/__init__.py +0 -0
  147. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/archive_msg.py +0 -0
  148. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/conf.py +0 -0
  149. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/jid_escaping.py +0 -0
  150. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/lock.py +0 -0
  151. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/test.py +0 -0
  152. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge/util/util.py +0 -0
  153. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/SOURCES.txt +0 -0
  154. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/dependency_links.txt +0 -0
  155. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/entry_points.txt +0 -0
  156. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/requires.txt +0 -0
  157. {slidge-0.3.0b2 → slidge-0.3.0b3}/slidge.egg-info/top_level.txt +0 -0
  158. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/__init__.py +0 -0
  159. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/__main__.py +0 -0
  160. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/contact.py +0 -0
  161. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/gateway.py +0 -0
  162. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/group.py +0 -0
  163. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/legacy_client.py +0 -0
  164. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/session.py +0 -0
  165. {slidge-0.3.0b2 → slidge-0.3.0b3}/superduper/util.py +0 -0
  166. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/conftest.py +0 -0
  167. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_adhoc/test_access.py +0 -0
  168. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_adhoc/test_confirmation.py +0 -0
  169. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_adhoc/test_form.py +0 -0
  170. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_adhoc/test_reported.py +0 -0
  171. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_avatar.py +0 -0
  172. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_backfill.py +0 -0
  173. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_chat_commands.py +0 -0
  174. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_config.py +0 -0
  175. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_db/test_store.py +0 -0
  176. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_db/test_user.py +0 -0
  177. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_feature_restriction.py +0 -0
  178. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_mam_archivable.py +0 -0
  179. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_mds.py +0 -0
  180. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_resourceprep.py +0 -0
  181. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_session.py +0 -0
  182. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_set_name_before_fill.py +0 -0
  183. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_stanza_link_preview.py +0 -0
  184. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_util.py +0 -0
  185. {slidge-0.3.0b2 → slidge-0.3.0b3}/tests/test_vcard.py +0 -0
  186. {slidge-0.3.0b2 → slidge-0.3.0b3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slidge
3
- Version: 0.3.0b2
3
+ Version: 0.3.0b3
4
4
  Summary: XMPP bridging framework
5
5
  Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -47,5 +47,10 @@ modules:
47
47
  both: slidge_rule
48
48
  message:
49
49
  outgoing: slidge_rule
50
+ iq:
51
+ "http://jabber.org/protocol/pubsub":
52
+ both: slidge_rule
53
+ "http://jabber.org/protocol/pubsub#owner":
54
+ set: slidge_rule
50
55
  mod_roster:
51
56
  versioning: true
@@ -60,12 +60,6 @@ for all changes to be taken into account
60
60
  Privileges with ejabberd
61
61
  ------------------------
62
62
 
63
- .. warning::
64
-
65
- If you want to set up privileges, you need ejabberd with version 23.10 or newer because of these two issues:
66
- https://github.com/processone/ejabberd/issues/3990 and
67
- https://github.com/processone/ejabberd/issues/3942
68
-
69
63
  .. code-block:: yaml
70
64
 
71
65
  acl:
@@ -87,3 +81,9 @@ Privileges with ejabberd
87
81
  outgoing: slidge_rule
88
82
  mod_roster:
89
83
  versioning: true
84
+
85
+ iq:
86
+ "http://jabber.org/protocol/pubsub":
87
+ both: slidge_rule
88
+ "http://jabber.org/protocol/pubsub#owner":
89
+ set: slidge_rule
@@ -303,6 +303,10 @@ class AttachmentMixin(TextMessageMixin):
303
303
  )
304
304
  if attachment.name:
305
305
  sfs["file"]["name"] = attachment.name
306
+ if attachment.disposition:
307
+ sfs["disposition"] = attachment.disposition
308
+ else:
309
+ del sfs["disposition"]
306
310
  if thumbnail is not None:
307
311
  sfs["file"].append(thumbnail)
308
312
  stored.sfs = str(sfs)
@@ -19,7 +19,7 @@ class Base:
19
19
  xmpp: "BaseGateway" = NotImplemented
20
20
 
21
21
  jid: JID = NotImplemented
22
- name: str = NotImplemented
22
+ name: str | None = NotImplemented
23
23
 
24
24
  @property
25
25
  def user_jid(self):
@@ -13,7 +13,7 @@ class BaseDiscoMixin(Base):
13
13
  DISCO_NAME: str = NotImplemented
14
14
  DISCO_LANG = None
15
15
 
16
- def _get_disco_name(self):
16
+ def _get_disco_name(self) -> str | None:
17
17
  if self.DISCO_NAME is NotImplemented:
18
18
  return self.xmpp.COMPONENT_NAME
19
19
  return self.DISCO_NAME or self.xmpp.COMPONENT_NAME
@@ -478,7 +478,7 @@ class ParticipantStore:
478
478
 
479
479
  @staticmethod
480
480
  def get_all(
481
- session, room_pk: int, user_included: bool = True
481
+ session: Session, room_pk: int, user_included: bool = True
482
482
  ) -> Iterator[Participant]:
483
483
  query = select(Participant).where(Participant.room_id == room_pk)
484
484
  if not user_included:
@@ -1,6 +1,6 @@
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
@@ -119,13 +119,31 @@ class LegacyBookmarks(
119
119
  return self.from_store(stored)
120
120
  return None
121
121
 
122
- async def by_legacy_id(self, legacy_id: LegacyGroupIdType) -> LegacyMUCType:
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:
123
138
  async with self.lock(("legacy_id", legacy_id)):
124
139
  local = await self.legacy_id_to_jid_local_part(legacy_id)
125
140
  jid = JID(f"{local}@{self.xmpp.boundjid}")
126
141
  if self.get_lock(("bare", jid.bare)):
127
142
  self.session.log.debug("Already updating %s via by_jid()", jid)
128
- return await self.by_jid(jid)
143
+ if create:
144
+ return await self.by_jid(jid)
145
+ else:
146
+ return self.by_jid_only_if_exists(jid)
129
147
 
130
148
  with self.xmpp.store.session() as orm:
131
149
  stored = (
@@ -7,7 +7,16 @@ from asyncio import Lock
7
7
  from contextlib import asynccontextmanager
8
8
  from copy import copy
9
9
  from datetime import datetime, timedelta, timezone
10
- from typing import TYPE_CHECKING, AsyncIterator, Generic, Optional, Type, Union
10
+ from typing import (
11
+ TYPE_CHECKING,
12
+ AsyncIterator,
13
+ Generic,
14
+ Literal,
15
+ Optional,
16
+ Type,
17
+ Union,
18
+ overload,
19
+ )
11
20
  from uuid import uuid4
12
21
 
13
22
  import sqlalchemy as sa
@@ -325,16 +334,15 @@ class LegacyMUC(
325
334
  self.stored.history_filled = True
326
335
  self.commit(merge=True)
327
336
 
328
- @property
329
- def DISCO_NAME(self) -> str: # type:ignore
330
- return self.name or "unnamed-room"
337
+ def _get_disco_name(self) -> str | None:
338
+ return self.name
331
339
 
332
340
  @property
333
- def name(self) -> str:
334
- return self.stored.name or "unnamed-room"
341
+ def name(self) -> str | None:
342
+ return self.stored.name
335
343
 
336
344
  @name.setter
337
- def name(self, n: str) -> None:
345
+ def name(self, n: str | None) -> None:
338
346
  if self.name == n:
339
347
  return
340
348
  self.stored.name = n
@@ -673,7 +681,7 @@ class LegacyMUC(
673
681
  since=since,
674
682
  )
675
683
  self.__get_subject_setter_participant().set_room_subject(
676
- self.subject if self.HAS_SUBJECT else (self.description or self.name),
684
+ self.subject if self.HAS_SUBJECT else (self.description or self.name or ""),
677
685
  user_full_jid,
678
686
  self.subject_date,
679
687
  )
@@ -764,9 +772,24 @@ class LegacyMUC(
764
772
  """
765
773
  return self._participant_cls(self, Participant(), is_system=True)
766
774
 
775
+ @overload
767
776
  async def get_participant_by_contact(
768
777
  self, c: "LegacyContact"
769
- ) -> "LegacyParticipantType":
778
+ ) -> "LegacyParticipantType": ...
779
+
780
+ @overload
781
+ async def get_participant_by_contact(
782
+ self, c: "LegacyContact", create: Literal[False]
783
+ ) -> "LegacyParticipantType | None": ...
784
+
785
+ @overload
786
+ async def get_participant_by_contact(
787
+ self, c: "LegacyContact", create: Literal[True]
788
+ ) -> "LegacyParticipantType": ...
789
+
790
+ async def get_participant_by_contact(
791
+ self, c: "LegacyContact", create: bool = True
792
+ ) -> "LegacyParticipantType | None":
770
793
  """
771
794
  Get a non-anonymous participant.
772
795
 
@@ -774,6 +797,7 @@ class LegacyMUC(
774
797
  that the Contact jid is associated to this participant
775
798
 
776
799
  :param c: The :class:`.LegacyContact` instance corresponding to this contact
800
+ :param create: Creates the participant if it does not exist.
777
801
  :return:
778
802
  """
779
803
  await self.session.contacts.ready
@@ -785,7 +809,10 @@ class LegacyMUC(
785
809
  .filter_by(contact=c.stored, room=self.stored)
786
810
  .one_or_none()
787
811
  )
788
- if stored is not None:
812
+ if stored is None:
813
+ if not create:
814
+ return None
815
+ else:
789
816
  return self.participant_from_store(stored=stored, contact=c)
790
817
 
791
818
  nickname = c.name or unescape_node(c.jid.node)
@@ -72,6 +72,7 @@ MucRole = Literal["visitor", "participant", "moderator", "none"]
72
72
  ClientType = Literal[
73
73
  "bot", "console", "game", "handheld", "pc", "phone", "sms", "tablet", "web"
74
74
  ]
75
+ AttachmentDisposition = Literal["attachment", "inline"]
75
76
 
76
77
 
77
78
  @dataclass
@@ -115,6 +116,7 @@ class LegacyAttachment:
115
116
  legacy_file_id: Optional[Union[str, int]] = None
116
117
  url: Optional[str] = None
117
118
  caption: Optional[str] = None
119
+ disposition: Optional[AttachmentDisposition] = None
118
120
  """
119
121
  A caption for this specific image. For a global caption for a list of attachments,
120
122
  use the ``body`` parameter of :meth:`.AttachmentMixin.send_files`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slidge
3
- Version: 0.3.0b2
3
+ Version: 0.3.0b3
4
4
  Summary: XMPP bridging framework
5
5
  Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -74,15 +74,18 @@ class Base(Shakespeare, AvatarFixtureMixin):
74
74
  use_values=False,
75
75
  )
76
76
 
77
- def _assert_file(self, url="http://url"):
77
+ def _assert_file(self, url="http://url", disposition: str = ''):
78
78
  when = (
79
79
  datetime.fromtimestamp(self.avatar_path.stat().st_mtime)
80
80
  .isoformat()
81
81
  .replace("+00:00", "Z")
82
82
  )
83
+ if disposition:
84
+ el = f"disposition='{disposition}'"
85
+ else:
86
+ el = ""
83
87
  self.send( # language=XML
84
- f"""
85
- <message type="chat"
88
+ f"""<message type="chat"
86
89
  from="juliet@aim.shakespeare.lit/slidge"
87
90
  to="romeo@montague.lit">
88
91
  <reference xmlns="urn:xmpp:reference:0"
@@ -108,8 +111,7 @@ class Base(Shakespeare, AvatarFixtureMixin):
108
111
  </file>
109
112
  </media-sharing>
110
113
  </reference>
111
- <file-sharing xmlns="urn:xmpp:sfs:0"
112
- disposition="inline">
114
+ <file-sharing xmlns="urn:xmpp:sfs:0" {el}>
113
115
  <sources>
114
116
  <url-data xmlns="http://jabber.org/protocol/url-data"
115
117
  target="{url}" />
@@ -153,13 +155,13 @@ class TestBodyOnly(Base):
153
155
 
154
156
 
155
157
  class TestAttachmentUpload(Base):
156
- def __test_basic(self, attachment: LegacyAttachment, upload_kwargs: dict):
158
+ def __test_basic(self, attachment: LegacyAttachment, upload_kwargs: dict, disposition: str = ''):
157
159
  """
158
160
  Basic test that file is uploaded.
159
161
  """
160
162
  self.run_coro(self.juliet.send_files([attachment]))
161
163
  self.http_upload.assert_called_with(**upload_kwargs)
162
- self._assert_file()
164
+ self._assert_file(disposition=disposition)
163
165
 
164
166
  def _test_reuse(self, attachment: LegacyAttachment, upload_kwargs: dict):
165
167
  """
@@ -185,6 +187,18 @@ class TestAttachmentUpload(Base):
185
187
  ),
186
188
  )
187
189
 
190
+ def test_path_attachment(self):
191
+ self.__test_basic(
192
+ LegacyAttachment(path=self.avatar_path, disposition="attachment"),
193
+ dict(
194
+ filename=self.avatar_path,
195
+ content_type="image/png",
196
+ ifrom=self.xmpp.boundjid,
197
+ domain=None,
198
+ ),
199
+ "attachment",
200
+ )
201
+
188
202
  def test_thumbhash(self):
189
203
  self.__test_basic(
190
204
  LegacyAttachment(path=self.avatar_path, content_type="image/png"),
@@ -441,8 +455,7 @@ class TestAttachmentNoUpload(Base):
441
455
  </file>
442
456
  </media-sharing>
443
457
  </reference>
444
- <file-sharing xmlns="urn:xmpp:sfs:0"
445
- disposition="inline">
458
+ <file-sharing xmlns="urn:xmpp:sfs:0">
446
459
  <sources>
447
460
  <url-data xmlns="http://jabber.org/protocol/url-data"
448
461
  target="https://url/uuid/uuid/5x5.png" />
@@ -4189,9 +4189,7 @@ class TestMUCAdmin(Base):
4189
4189
  </field>
4190
4190
  <field label='Natural-Language Room Name'
4191
4191
  type='text-single'
4192
- var='muc#roomconfig_roomname'>
4193
- <value>unnamed-room</value>
4194
- </field>
4192
+ var='muc#roomconfig_roomname'></field>
4195
4193
  <field label='Short Description of Room'
4196
4194
  type='text-single'
4197
4195
  var='muc#roomconfig_roomdesc'>
@@ -355,8 +355,7 @@ class TestSession2(AvatarFixtureMixin, SlidgeTest):
355
355
  </presence>
356
356
  """
357
357
  )
358
- subject = self.next_sent()
359
- assert subject["subject"] == "unnamed-room"
358
+ _subject = self.next_sent()
360
359
  self.send( # language=XML
361
360
  """
362
361
  <presence to="romeo@montague.lit/movim"
@@ -502,3 +501,82 @@ class TestSession2(AvatarFixtureMixin, SlidgeTest):
502
501
  </presence>
503
502
  """
504
503
  )
504
+
505
+ def test_disco_unnamed_room(self):
506
+ self.recv( # language=XML
507
+ f"""
508
+ <iq type="get"
509
+ from="romeo@montague.lit/gajim"
510
+ to="room-noinfo@{self.xmpp.boundjid.bare}"
511
+ id="123">
512
+ <query xmlns='http://jabber.org/protocol/disco#info' />
513
+ </iq>
514
+ """
515
+ )
516
+ self.send( # language=XML
517
+ f"""
518
+ <iq xmlns="jabber:component:accept"
519
+ type="result"
520
+ from="room-noinfo@aim.shakespeare.lit"
521
+ to="romeo@montague.lit/gajim"
522
+ id="123">
523
+ <query xmlns="http://jabber.org/protocol/disco#info">
524
+ <identity category="conference"
525
+ type="text" />
526
+ <feature var="http://jabber.org/protocol/muc" />
527
+ <feature var="http://jabber.org/protocol/muc#stable_id" />
528
+ <feature var="http://jabber.org/protocol/muc#self-ping-optimization" />
529
+ <feature var="urn:xmpp:mam:2" />
530
+ <feature var="urn:xmpp:mam:2#extended" />
531
+ <feature var="urn:xmpp:sid:0" />
532
+ <feature var="muc_persistent" />
533
+ <feature var="vcard-temp" />
534
+ <feature var="urn:xmpp:ping" />
535
+ <feature var="urn:xmpp:occupant-id:0" />
536
+ <feature var="jabber:iq:register" />
537
+ <feature var="urn:xmpp:message-moderate:1" />
538
+ <feature var="muc_open" />
539
+ <feature var="muc_semianonymous" />
540
+ <feature var="muc_public" />
541
+ <x xmlns="jabber:x:data"
542
+ type="result">
543
+ <field var="FORM_TYPE"
544
+ type="hidden">
545
+ <value>http://jabber.org/protocol/muc#roominfo</value>
546
+ </field>
547
+ <field var="muc#roomconfig_persistentroom"
548
+ type="boolean">
549
+ <value>1</value>
550
+ </field>
551
+ <field var="muc#roomconfig_changesubject"
552
+ type="boolean">
553
+ <value>0</value>
554
+ </field>
555
+ <field var="muc#maxhistoryfetch">
556
+ <value>100</value>
557
+ </field>
558
+ <field var="muc#roominfo_subjectmod"
559
+ type="boolean">
560
+ <value>0</value>
561
+ </field>
562
+ <field var="muc#roomconfig_membersonly"
563
+ type="boolean">
564
+ <value>0</value>
565
+ </field>
566
+ <field var="muc#roomconfig_whois"
567
+ type="list-single">
568
+ <value>moderators</value>
569
+ </field>
570
+ <field var="muc#roomconfig_publicroom"
571
+ type="boolean">
572
+ <value>1</value>
573
+ </field>
574
+ <field var="muc#roomconfig_allowpm"
575
+ type="boolean">
576
+ <value>0</value>
577
+ </field>
578
+ </x>
579
+ </query>
580
+ </iq>
581
+ """,
582
+ )
@@ -1841,8 +1841,7 @@ class TestCarbon(ClearSessionMixin, SlidgeTest):
1841
1841
  </file>
1842
1842
  </media-sharing>
1843
1843
  </reference>
1844
- <file-sharing xmlns="urn:xmpp:sfs:0"
1845
- disposition="inline">
1844
+ <file-sharing xmlns="urn:xmpp:sfs:0">
1846
1845
  <sources>
1847
1846
  <url-data xmlns="http://jabber.org/protocol/url-data"
1848
1847
  target="URL" />
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
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
File without changes
File without changes