slidge 0.2.3.post1__tar.gz → 0.2.5__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/package.yaml +5 -0
  2. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/test.yaml +1 -1
  3. {slidge-0.2.3.post1 → slidge-0.2.5}/Dockerfile +1 -1
  4. {slidge-0.2.3.post1/slidge.egg-info → slidge-0.2.5}/PKG-INFO +7 -6
  5. {slidge-0.2.3.post1 → slidge-0.2.5}/README.md +4 -4
  6. slidge-0.2.5/commitlint.config.js +30 -0
  7. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/confs/slidge-example.ini +1 -1
  8. {slidge-0.2.3.post1 → slidge-0.2.5}/doap.xml +22 -0
  9. {slidge-0.2.3.post1 → slidge-0.2.5}/docker-compose.yml +1 -1
  10. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/install.rst +1 -1
  11. slidge-0.2.5/docs/source/admin/note.rst +12 -0
  12. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/dev/tutorial.rst +2 -2
  13. slidge-0.2.5/docs/source/user/note.rst +13 -0
  14. {slidge-0.2.3.post1 → slidge-0.2.5}/pyproject.toml +53 -2
  15. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/__version__.py +1 -1
  16. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/base.py +6 -2
  17. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/contact/contact.py +1 -1
  18. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/config.py +12 -1
  19. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/message/message.py +4 -1
  20. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/gateway.py +14 -2
  21. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/attachment.py +1 -0
  22. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/message.py +1 -1
  23. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/recipient.py +2 -2
  24. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/pubsub.py +2 -1
  25. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/avatar.py +20 -1
  26. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/store.py +2 -0
  27. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/group/participant.py +9 -1
  28. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/group/room.py +21 -1
  29. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/__init__.py +72 -5
  30. slidge-0.2.5/slidge/slixfix/xep_0492/__init__.py +8 -0
  31. slidge-0.2.5/slidge/slixfix/xep_0492/notify.py +16 -0
  32. slidge-0.2.5/slidge/slixfix/xep_0492/stanza.py +102 -0
  33. {slidge-0.2.3.post1 → slidge-0.2.5/slidge.egg-info}/PKG-INFO +7 -6
  34. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge.egg-info/SOURCES.txt +3 -0
  35. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/conftest.py +3 -0
  36. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_feature_restriction.py +1 -1
  37. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_muc.py +296 -4
  38. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_shakespeare.py +2 -1
  39. slidge-0.2.3.post1/commitlint.config.js +0 -2
  40. slidge-0.2.3.post1/docs/source/admin/note.rst +0 -12
  41. slidge-0.2.3.post1/docs/source/user/note.rst +0 -13
  42. {slidge-0.2.3.post1 → slidge-0.2.5}/.gitignore +0 -0
  43. {slidge-0.2.3.post1 → slidge-0.2.5}/.pre-commit-config.yaml +0 -0
  44. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/container-cache.yml +0 -0
  45. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/container-ci.yaml +0 -0
  46. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/container.yml +0 -0
  47. {slidge-0.2.3.post1 → slidge-0.2.5}/.woodpecker/docs.yaml +0 -0
  48. {slidge-0.2.3.post1 → slidge-0.2.5}/LICENSE +0 -0
  49. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/5x5.png +0 -0
  50. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/slidge-color-small.png +0 -0
  51. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/slidge-color.png +0 -0
  52. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/slidge-mono-black.png +0 -0
  53. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/slidge-mono-white.png +0 -0
  54. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/assets/slidge.svg +0 -0
  55. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/confs/movim.env +0 -0
  56. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/confs/nginx.conf +0 -0
  57. {slidge-0.2.3.post1 → slidge-0.2.5}/dev/prettify_tests.py +0 -0
  58. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/Makefile +0 -0
  59. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/attachments.rst +0 -0
  60. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/component.rst +0 -0
  61. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/config/index.rst +0 -0
  62. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/daemon.rst +0 -0
  63. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/examples/ejabberd.yaml +0 -0
  64. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/examples/index.rst +0 -0
  65. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/examples/prosody.cfg.lua +0 -0
  66. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/index.rst +0 -0
  67. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/admin/privilege.rst +0 -0
  68. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/codeberg.svg +0 -0
  69. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/conf.py +0 -0
  70. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/dev/contributing.rst +0 -0
  71. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/dev/design.rst +0 -0
  72. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/dev/howto.rst +0 -0
  73. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/dev/index.rst +0 -0
  74. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/glossary.rst +0 -0
  75. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/index.rst +0 -0
  76. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/commands.rst +0 -0
  77. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/contacts.rst +0 -0
  78. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/foxyproxy.png +0 -0
  79. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/gajim.png +0 -0
  80. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/index.rst +0 -0
  81. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/low_profile.rst +0 -0
  82. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/movim1.png +0 -0
  83. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/movim2.png +0 -0
  84. {slidge-0.2.3.post1 → slidge-0.2.5}/docs/source/user/register.rst +0 -0
  85. {slidge-0.2.3.post1 → slidge-0.2.5}/setup.cfg +0 -0
  86. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/__init__.py +0 -0
  87. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/__main__.py +0 -0
  88. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/__init__.py +0 -0
  89. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/adhoc.py +0 -0
  90. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/admin.py +0 -0
  91. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/categories.py +0 -0
  92. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/chat_command.py +0 -0
  93. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/register.py +0 -0
  94. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/command/user.py +0 -0
  95. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/contact/__init__.py +0 -0
  96. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/contact/roster.py +0 -0
  97. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/__init__.py +0 -0
  98. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/__init__.py +0 -0
  99. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/caps.py +0 -0
  100. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/disco.py +0 -0
  101. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/message/__init__.py +0 -0
  102. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/message/chat_state.py +0 -0
  103. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/message/marker.py +0 -0
  104. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/__init__.py +0 -0
  105. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/admin.py +0 -0
  106. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/mam.py +0 -0
  107. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/misc.py +0 -0
  108. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/owner.py +0 -0
  109. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/muc/ping.py +0 -0
  110. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/presence.py +0 -0
  111. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/registration.py +0 -0
  112. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/search.py +0 -0
  113. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/session_dispatcher.py +0 -0
  114. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/util.py +0 -0
  115. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/dispatcher/vcard.py +0 -0
  116. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/__init__.py +0 -0
  117. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/avatar.py +0 -0
  118. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/base.py +0 -0
  119. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/db.py +0 -0
  120. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/disco.py +0 -0
  121. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/lock.py +0 -0
  122. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/message_maker.py +0 -0
  123. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/message_text.py +0 -0
  124. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/mixins/presence.py +0 -0
  125. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/core/session.py +0 -0
  126. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/__init__.py +0 -0
  127. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/__init__.py +0 -0
  128. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/env.py +0 -0
  129. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/old_user_store.py +0 -0
  130. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/script.py.mako +0 -0
  131. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
  132. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -0
  133. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
  134. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
  135. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
  136. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
  137. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -0
  138. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
  139. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
  140. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
  141. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
  142. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
  143. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
  144. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
  145. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
  146. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
  147. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
  148. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/meta.py +0 -0
  149. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/db/models.py +0 -0
  150. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/group/__init__.py +0 -0
  151. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/group/archive.py +0 -0
  152. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/group/bookmarks.py +0 -0
  153. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/main.py +0 -0
  154. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/migration.py +0 -0
  155. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/py.typed +0 -0
  156. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/delivery_receipt.py +0 -0
  157. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/link_preview/__init__.py +0 -0
  158. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/link_preview/link_preview.py +0 -0
  159. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/link_preview/stanza.py +0 -0
  160. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/roster.py +0 -0
  161. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0077/__init__.py +0 -0
  162. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0077/register.py +0 -0
  163. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0077/stanza.py +0 -0
  164. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0100/__init__.py +0 -0
  165. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0100/gateway.py +0 -0
  166. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0100/stanza.py +0 -0
  167. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0153/__init__.py +0 -0
  168. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
  169. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0292/__init__.py +0 -0
  170. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0292/vcard4.py +0 -0
  171. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0356_old/__init__.py +0 -0
  172. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0356_old/privilege.py +0 -0
  173. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/slixfix/xep_0356_old/stanza.py +0 -0
  174. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/__init__.py +0 -0
  175. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/archive_msg.py +0 -0
  176. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/conf.py +0 -0
  177. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/db.py +0 -0
  178. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/test.py +0 -0
  179. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/types.py +0 -0
  180. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge/util/util.py +0 -0
  181. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge.egg-info/dependency_links.txt +0 -0
  182. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge.egg-info/entry_points.txt +0 -0
  183. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge.egg-info/requires.txt +0 -0
  184. {slidge-0.2.3.post1 → slidge-0.2.5}/slidge.egg-info/top_level.txt +0 -0
  185. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/__init__.py +0 -0
  186. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/contact.py +0 -0
  187. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/gateway.py +0 -0
  188. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/group.py +0 -0
  189. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/legacy_client.py +0 -0
  190. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/session.py +0 -0
  191. {slidge-0.2.3.post1 → slidge-0.2.5}/superduper/util.py +0 -0
  192. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_adhoc/test_access.py +0 -0
  193. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_adhoc/test_confirmation.py +0 -0
  194. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_adhoc/test_form.py +0 -0
  195. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_adhoc/test_reported.py +0 -0
  196. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_attachment.py +0 -0
  197. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_avatar.py +0 -0
  198. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_backfill.py +0 -0
  199. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_chat_commands.py +0 -0
  200. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_config.py +0 -0
  201. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_db/test_store.py +0 -0
  202. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_db/test_user.py +0 -0
  203. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_mds.py +0 -0
  204. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_name_in_constructor.py +0 -0
  205. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_resourceprep.py +0 -0
  206. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_session.py +0 -0
  207. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_session_2.py +0 -0
  208. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_set_name_before_fill.py +0 -0
  209. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_stanza_link_preview.py +0 -0
  210. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_util.py +0 -0
  211. {slidge-0.2.3.post1 → slidge-0.2.5}/tests/test_vcard.py +0 -0
  212. {slidge-0.2.3.post1 → slidge-0.2.5}/uv.lock +0 -0
@@ -13,6 +13,10 @@ steps:
13
13
  version:
14
14
  image: codeberg.org/slidge/woodpecker-version
15
15
 
16
+ changelog:
17
+ image: codeberg.org/slidge/woodpecker-generate-changelog
18
+ pull: true
19
+
16
20
  build:
17
21
  image: *image
18
22
  commands:
@@ -49,3 +53,4 @@ steps:
49
53
  - dist/slidge*
50
54
  api_key:
51
55
  from_secret: CODEBERG_TOKEN
56
+ note: CHANGELOG
@@ -60,5 +60,5 @@ steps:
60
60
  token:
61
61
  from_secret: CODEBERG_TOKEN
62
62
  html-root: htmlcov
63
- root: coverage
63
+ prefix: coverage
64
64
  <<: *only-once
@@ -71,7 +71,7 @@ FROM base AS dev
71
71
 
72
72
  USER root
73
73
 
74
- COPY --from=docker.io/nicocool84/slidge-prosody-dev:latest \
74
+ COPY --from=codeberg.org/slidge/prosody-slidge-dev:latest \
75
75
  /etc/prosody/certs/localhost.crt \
76
76
  /usr/local/share/ca-certificates/
77
77
  RUN update-ca-certificates
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: slidge
3
- Version: 0.2.3.post1
3
+ Version: 0.2.5
4
4
  Summary: XMPP bridging framework
5
5
  Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -669,7 +669,8 @@ Project-URL: Homepage, https://codeberg.org/slidge/
669
669
  Project-URL: Issues, https://codeberg.org/slidge/slidge/issues
670
670
  Project-URL: Repository, https://codeberg.org/slidge/slidge/
671
671
  Project-URL: Chat room, https://conference.nicoco.fr:5281/muc_log/slidge/
672
- Project-URL: Documentation, https://slidge.codeberg.page/docs/main
672
+ Project-URL: Documentation, https://slidge.im/docs/slidge/main
673
+ Project-URL: changelog, https://codeberg.org/slidge/slidge/releases
673
674
  Keywords: xmpp,gateway,bridge,instant messaging
674
675
  Classifier: Topic :: Internet :: XMPP
675
676
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -693,14 +694,14 @@ Requires-Dist: thumbhash>=0.1.2
693
694
 
694
695
 
695
696
  [![woodpecker CI status](https://ci.codeberg.org/api/badges/14027/status.svg)](https://ci.codeberg.org/repos/14027)
696
- [![coverage](https://slidge.codeberg.page/coverage/main/coverage.svg)](https://slidge.im/coverage)
697
+ [![coverage](https://slidge.im/coverage/main/coverage.svg)](https://slidge.im/coverage/main)
697
698
 
698
699
  [![pypi version](https://badge.fury.io/py/slidge.svg)](https://pypi.org/project/slidge/)
699
700
  [![debian unstable version](https://badges.debian.net/badges/debian/unstable/python3-slidge/version.svg)](https://packages.debian.org/unstable/python3-slidge)
700
701
 
701
702
  Slidge is an XMPP (puppeteer) gateway library in python.
702
703
  It makes
703
- [writing gateways to other chat networks](https://slidge.im/core/dev/tutorial.html)
704
+ [writing gateways to other chat networks](https://slidge.im/docs/slidge/main/dev/tutorial.html)
704
705
  (*legacy modules*) as frictionless as possible.
705
706
  It supports fancy IM features, such as
706
707
  [(emoji) reactions](https://xmpp.org/extensions/xep-0444.html),
@@ -751,7 +752,7 @@ class Session(BaseSession):
751
752
  self.legacy_client.send_message(text=text, destination=chat.legacy_id)
752
753
  ```
753
754
 
754
- There's more in [the tutorial](https://slidge.codeberg.page/docs/main/dev/tutorial.html)!
755
+ There's more in [the tutorial](https://slidge.im/docs/slidge/main/dev/tutorial.html)!
755
756
 
756
757
  Installation
757
758
  ------------
@@ -766,7 +767,7 @@ bundle.
766
767
  Slidge is available on
767
768
  [codeberg](https://codeberg.org/slidge/-/packages) (python packages and containers)
768
769
  and [pypi](https://pypi.org/project/slidge/).
769
- Refer to [the docs](https://slidge.codeberg.page/docs/main/admin/install.html) for details.
770
+ Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
770
771
 
771
772
  About privacy
772
773
  -------------
@@ -4,14 +4,14 @@
4
4
 
5
5
 
6
6
  [![woodpecker CI status](https://ci.codeberg.org/api/badges/14027/status.svg)](https://ci.codeberg.org/repos/14027)
7
- [![coverage](https://slidge.codeberg.page/coverage/main/coverage.svg)](https://slidge.im/coverage)
7
+ [![coverage](https://slidge.im/coverage/main/coverage.svg)](https://slidge.im/coverage/main)
8
8
 
9
9
  [![pypi version](https://badge.fury.io/py/slidge.svg)](https://pypi.org/project/slidge/)
10
10
  [![debian unstable version](https://badges.debian.net/badges/debian/unstable/python3-slidge/version.svg)](https://packages.debian.org/unstable/python3-slidge)
11
11
 
12
12
  Slidge is an XMPP (puppeteer) gateway library in python.
13
13
  It makes
14
- [writing gateways to other chat networks](https://slidge.im/core/dev/tutorial.html)
14
+ [writing gateways to other chat networks](https://slidge.im/docs/slidge/main/dev/tutorial.html)
15
15
  (*legacy modules*) as frictionless as possible.
16
16
  It supports fancy IM features, such as
17
17
  [(emoji) reactions](https://xmpp.org/extensions/xep-0444.html),
@@ -62,7 +62,7 @@ class Session(BaseSession):
62
62
  self.legacy_client.send_message(text=text, destination=chat.legacy_id)
63
63
  ```
64
64
 
65
- There's more in [the tutorial](https://slidge.codeberg.page/docs/main/dev/tutorial.html)!
65
+ There's more in [the tutorial](https://slidge.im/docs/slidge/main/dev/tutorial.html)!
66
66
 
67
67
  Installation
68
68
  ------------
@@ -77,7 +77,7 @@ bundle.
77
77
  Slidge is available on
78
78
  [codeberg](https://codeberg.org/slidge/-/packages) (python packages and containers)
79
79
  and [pypi](https://pypi.org/project/slidge/).
80
- Refer to [the docs](https://slidge.codeberg.page/docs/main/admin/install.html) for details.
80
+ Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
81
81
 
82
82
  About privacy
83
83
  -------------
@@ -0,0 +1,30 @@
1
+ // This files defines the allowed "headers" for the commit messages.
2
+ // Following the rules makes the changelog generation easier.
3
+ // They come from angular conventions, unless commented.
4
+ const Configuration = {
5
+ extends: ['@commitlint/config-conventional'],
6
+ rules: {
7
+ 'type-enum':
8
+ [
9
+ 2,
10
+ 'always',
11
+ [
12
+ 'build',
13
+ 'chore',
14
+ 'ci',
15
+ 'docs',
16
+ 'feat',
17
+ 'fix',
18
+ 'perf',
19
+ 'refactor',
20
+ 'revert',
21
+ 'style',
22
+ 'test',
23
+ 'compat', // workaround to play nice with non-compliant clients or servers; ideally reverted once fixed upstream
24
+ 'cfix', // fixes an unreleased commit, should not appear in changelog
25
+ ]
26
+ ],
27
+ },
28
+ }
29
+
30
+ module.exports = Configuration
@@ -1,4 +1,4 @@
1
- # More info at https://slidge.codeberg.page/docs/main/admin/config
1
+ # More info at https://slidge.im/docs/slidge/main/admin/config
2
2
 
3
3
  # The slidge 'plugin' to use, ie, the name of the legacy service
4
4
  # legacy-module=slidge.plugins.discord
@@ -410,6 +410,12 @@
410
410
  <xmpp:note>Will implement if useful for a plugin.</xmpp:note>
411
411
  </xmpp:SupportedXep>
412
412
  </implements>
413
+ <implements>
414
+ <xmpp:SupportedXep>
415
+ <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0384.html"/>
416
+ <xmpp:status>complete</xmpp:status>
417
+ </xmpp:SupportedXep>
418
+ </implements>
413
419
  <implements>
414
420
  <xmpp:SupportedXep>
415
421
  <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0385.html"/>
@@ -485,6 +491,14 @@
485
491
  <xmpp:note>Legacy service to XMPP attachments have SFS metadata when possible. Not supported from XMPP to legacy service</xmpp:note>
486
492
  </xmpp:SupportedXep>
487
493
  </implements>
494
+ <implements>
495
+ <xmpp:SupportedXep>
496
+ <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0469.html"/>
497
+ <xmpp:status>complete</xmpp:status>
498
+ <xmpp:version>0.1.0</xmpp:version>
499
+ <xmpp:note>Relies on being a privileged entity (XEP-0356), to edit bookmark entries.</xmpp:note>
500
+ </xmpp:SupportedXep>
501
+ </implements>
488
502
  <implements>
489
503
  <xmpp:SupportedXep>
490
504
  <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0486.html"/>
@@ -502,5 +516,13 @@
502
516
  <xmpp:note>Slidge supports listening to MDS events and triggering "legacy MDS" events, if added to the PEP MDS node, which is done automatically if XEP-0356 IQ privileges are set. Slidge also support updating MDS node in reaction to "legacy MDS" events.</xmpp:note>
503
517
  </xmpp:SupportedXep>
504
518
  </implements>
519
+ <implements>
520
+ <xmpp:SupportedXep>
521
+ <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0492.html"/>
522
+ <xmpp:status>partial</xmpp:status>
523
+ <xmpp:version>0.1.0</xmpp:version>
524
+ <xmpp:note>Per client-type setting is not supported.</xmpp:note>
525
+ </xmpp:SupportedXep>
526
+ </implements>
505
527
  </Project>
506
528
  </rdf:RDF>
@@ -16,7 +16,7 @@ services:
16
16
  - prosody
17
17
 
18
18
  prosody:
19
- image: docker.io/nicocool84/slidge-prosody-dev:latest
19
+ image: codeberg.org/slidge/slidge-prosody-dev:latest
20
20
  ports:
21
21
  - "127.0.0.1:5281:5281" # XMPP port for clients to connect to
22
22
  - "127.0.0.1:5222:5222" # prosody's http_file_share
@@ -5,7 +5,7 @@ Installation
5
5
  Dockerhub
6
6
  ---------
7
7
 
8
- Containers for arm64 and amd64 are available on `docker hub <https://hub.docker.com/u/nicocool84>`_.
8
+ Containers for arm64 and amd64 are available on `codeberg <https://codeberg.org/slidge/-/packages?q=&type=container>`_.
9
9
  The slidge-whatsapp arm64 container is kindly provided by `raver <https://hub.docker.com/u/ravermeister>`_.
10
10
  See :ref:`Containers` for more details.
11
11
 
@@ -0,0 +1,12 @@
1
+ .. note::
2
+
3
+ For legacy module-specific options, refer to their own docs:
4
+ `matridge <https://slidge.im/docs/matridge/main/config.html>`_,
5
+ `matteridge <https://slidge.im/docs/matteridge/main/config.html>`_,
6
+ `messlidger <https://slidge.im/docs/messlidger/main/config.html>`_,
7
+ `skidge <https://slidge.im/docs/skidge/main/config.html>`_,
8
+ `sleamdge <https://slidge.im/docs/sleamdge/main/config.html>`_,
9
+ `slidcord <https://slidge.im/docs/slidcord/main/config.html>`_,
10
+ `slidge-whatsapp <https://slidge.im/docs/slidge-whatsapp/main/config.html>`_,
11
+ `slidgnal <https://slidge.im/docs/slidgnal/main/config.html>`_,
12
+ `slidgram <https://slidge.im/docs/slidgram/main/config.html>`_.
@@ -40,7 +40,7 @@ Put this in a file called ``superduper.py``:
40
40
  contact = await self.contacts.by_legacy_id(msg.sender)
41
41
  contact.send_text(msg.text)
42
42
 
43
- async def send_text(self, chat: Recipient, text: str, *kwargs):
43
+ async def on_text(self, chat: Recipient, text: str, *kwargs):
44
44
  self.legacy.send_message(text=text, destination=chat.legacy_id)
45
45
 
46
46
 
@@ -123,7 +123,7 @@ From XMPP to legacy
123
123
 
124
124
  .. code-block:: python
125
125
 
126
- async def send_text(self, chat: Recipient, text: str, **kwargs):
126
+ async def on_text(self, chat: Recipient, text: str, **kwargs):
127
127
  self.legacy.send_message(text=text, destination=chat.legacy_id)
128
128
 
129
129
  When our user sends a message to ``something@superduper.example.org``,
@@ -0,0 +1,13 @@
1
+ .. note::
2
+
3
+ These are the generic user docs for slidge. For
4
+ :term:`Legacy Network`-specific docs, follow these links:
5
+ `matridge <https://slidge.im/docs/matridge/main/user.html>`_,
6
+ `matteridge <https://slidge.im/docs/matteridge/main/user.html>`_,
7
+ `messlidger <https://slidge.im/docs/messlidger/main/user.html>`_,
8
+ `skidge <https://slidge.im/docs/skidge/main/user.html>`_,
9
+ `sleamdge <https://slidge.im/docs/sleamdge/main/user.html>`_,
10
+ `slidcord <https://slidge.im/docs/slidcord/main/user.html>`_,
11
+ `slidge-whatsapp <https://slidge.im/docs/slidge-whatsapp/main/user.html>`_,
12
+ `slidgnal <https://slidge.im/docs/slidgnal/main/user.html>`_,
13
+ `slidgram <https://slidge.im/docs/slidgram/main/user.html>`_.
@@ -24,7 +24,7 @@ classifiers = [
24
24
  "Topic :: Software Development :: Libraries :: Python Modules",
25
25
  ]
26
26
  keywords = ["xmpp", "gateway", "bridge", "instant messaging"]
27
- version = "v0.2.3.post1"
27
+ version = "v0.2.5"
28
28
  readme = "README.md"
29
29
 
30
30
  [build-system]
@@ -42,7 +42,8 @@ Homepage = "https://codeberg.org/slidge/"
42
42
  Issues = "https://codeberg.org/slidge/slidge/issues"
43
43
  Repository = "https://codeberg.org/slidge/slidge/"
44
44
  "Chat room" = "https://conference.nicoco.fr:5281/muc_log/slidge/"
45
- Documentation = "https://slidge.codeberg.page/docs/main"
45
+ Documentation = "https://slidge.im/docs/slidge/main"
46
+ changelog = "https://codeberg.org/slidge/slidge/releases"
46
47
 
47
48
  [dependency-groups]
48
49
  dev = [
@@ -115,3 +116,53 @@ publish-url = "https://codeberg.org/api/packages/slidge/pypi"
115
116
  # FIXME: remove this when the setuptools upstream bug is fixed
116
117
  # https://github.com/astral-sh/uv/issues/9513#issuecomment-2519527822
117
118
  license-files = []
119
+
120
+
121
+ [tool.git-cliff.remote.gitea]
122
+ owner = "slidge"
123
+ repo = "slidge"
124
+
125
+ [tool.git-cliff.changelog]
126
+ header = """
127
+ <!-- write something cool about the release here! -->
128
+
129
+ # Changes
130
+ """
131
+ body = """
132
+ {% for group, commits in commits | group_by(attribute="group") %}
133
+ ## {{ group | striptags | trim | upper_first }}
134
+ {% for commit in commits %}
135
+ - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
136
+ {% if commit.breaking %}[**breaking**] {% endif %}\
137
+ {{ commit.message | split(pat="\n") | first | upper_first | trim }}\
138
+ {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %} \
139
+ [`{{ commit.id | truncate(length=7, end="") }}`](./commit/{{ commit.id }})\
140
+ {% endfor %}
141
+ {% endfor %}\n
142
+ """
143
+ footer = """
144
+ <!-- generated by git-cliff -->
145
+ """
146
+
147
+ [tool.git-cliff.git]
148
+ conventional_commits = true
149
+ filter_unconventional = false
150
+ commit_parsers = [
151
+ { message = "^feat", group = "<!-- 0 -->🚀 Features" },
152
+ { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
153
+ { message = "^compat", group = "<!-- 2 -->💑 Compatibility" },
154
+ { message = "^refactor", group = "<!-- 3 -->🚜 Refactor" },
155
+ { message = "^doc", group = "<!-- 4 -->📚 Documentation" },
156
+ { message = "^perf", group = "<!-- 5 -->⚡ Performance" },
157
+ { message = "^style", group = "<!-- 6 -->🎨 Styling" },
158
+ { message = "^test", group = "<!-- 7 -->🧪 Testing" },
159
+ { message = "^chore\\(release\\): prepare for", skip = true },
160
+ { message = "^chore\\(deps.*\\)", skip = true },
161
+ { message = "^chore\\(pr\\)", skip = true },
162
+ { message = "^chore\\(pull\\)", skip = true },
163
+ { message = "^cfix", skip = true },
164
+ { message = "^chore|^ci", group = "<!-- 8 -->⚙️ Miscellaneous Tasks" },
165
+ { body = ".*security", group = "<!-- 9 -->🛡️ Security" },
166
+ { message = "^revert", group = "<!-- 10 -->◀️ Revert" },
167
+ { message = ".*", group = "<!-- 11 -->💼 Other" },
168
+ ]
@@ -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__ = "v0.2.3.post1"
5
+ __version__ = "v0.2.5"
@@ -293,12 +293,16 @@ class FormField:
293
293
  return value
294
294
 
295
295
  def __validate_list_multi(self, value: list[str]) -> Union[list[str], list[JID]]:
296
+ # COMPAT: all the "if v" and "if not v" are workarounds for https://codeberg.org/slidge/slidge/issues/43
297
+ # They should be reverted once the bug is fixed upstream, cf https://soprani.ca/todo/390
296
298
  for v in value:
297
299
  if v not in self.__acceptable_options():
300
+ if not v:
301
+ continue
298
302
  raise XMPPError("not-acceptable", f"Not a valid option: '{v}'")
299
303
  if self.type == "list-multi":
300
- return value
301
- return [JID(v) for v in value]
304
+ return [v for v in value if v]
305
+ return [JID(v) for v in value if v]
302
306
 
303
307
  def get_xml(self) -> SlixFormField:
304
308
  """
@@ -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.codeberg.page/docs/main/admin/privilege.html for"
457
+ " to https://slidge.im/docs/slidge/main/admin/privilege.html for"
458
458
  " more info."
459
459
  )
460
460
  if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
@@ -187,7 +187,7 @@ MAM_MAX_DAYS__DOC = "Maximum number of days for group archive retention."
187
187
  CORRECTION_EMPTY_BODY_AS_RETRACTION = True
188
188
  CORRECTION_EMPTY_BODY_AS_RETRACTION__DOC = (
189
189
  "Treat last message correction to empty message as a retraction. "
190
- "(this is what cheogram do for retraction)"
190
+ "(this is what cheogram does for retraction)"
191
191
  )
192
192
 
193
193
  ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH = 200
@@ -220,3 +220,14 @@ STRIP_LEADING_EMOJI_ADHOC__DOC = (
220
220
  "Strip the leading emoji in ad-hoc command names, if present, in case you "
221
221
  "are a emoji-hater."
222
222
  )
223
+
224
+ COMPONENT_NAME: Optional[str] = None
225
+ COMPONENT_NAME__DOC = (
226
+ "Overrides the default component name with a custom one. This is seen in service discovery and as the nickname "
227
+ "of the component in chat windows."
228
+ )
229
+
230
+ WELCOME_MESSAGE: Optional[str] = None
231
+ WELCOME_MESSAGE__DOC = (
232
+ "Overrides the default welcome message received by newly registered users."
233
+ )
@@ -296,7 +296,10 @@ class MessageContentMixin(DispatcherMixin):
296
296
  # no need to carbon for groups, we just don't echo the stanza
297
297
  entity.react(legacy_id, carbon=True) # type: ignore
298
298
  await session.on_react(entity, legacy_id, [], thread=thread)
299
- raise XMPPError("not-acceptable", text=error_msg)
299
+ raise XMPPError(
300
+ "policy-violation", # type:ignore
301
+ text=error_msg,
302
+ )
300
303
 
301
304
  await session.on_react(entity, legacy_id, emojis, thread=thread)
302
305
  if isinstance(entity, LegacyMUC):
@@ -254,6 +254,10 @@ class BaseGateway(
254
254
  http: aiohttp.ClientSession
255
255
 
256
256
  def __init__(self):
257
+ if config.COMPONENT_NAME:
258
+ self.COMPONENT_NAME = config.COMPONENT_NAME
259
+ if config.WELCOME_MESSAGE:
260
+ self.WELCOME_MESSAGE = config.WELCOME_MESSAGE
257
261
  self.log = log
258
262
  self.datetime_started = datetime.now()
259
263
  self.xmpp = self # ugly hack to work with the BaseSender mixin :/
@@ -416,8 +420,14 @@ class BaseGateway(
416
420
  await self.plugin["xep_0115"].update_caps(jid=self.boundjid)
417
421
 
418
422
  if self.COMPONENT_AVATAR is not None:
419
- cached_avatar = await avatar_cache.convert_or_get(self.COMPONENT_AVATAR)
420
- self.avatar_pk = cached_avatar.pk
423
+ try:
424
+ cached_avatar = await avatar_cache.convert_or_get(self.COMPONENT_AVATAR)
425
+ except Exception as e:
426
+ log.exception("Could not set the component avatar.", exc_info=e)
427
+ cached_avatar = None
428
+ else:
429
+ assert cached_avatar is not None
430
+ self.avatar_pk = cached_avatar.pk
421
431
  else:
422
432
  cached_avatar = None
423
433
 
@@ -913,7 +923,9 @@ SLIXMPP_PLUGINS = [
913
923
  "xep_0444", # Message reactions
914
924
  "xep_0447", # Stateless File Sharing
915
925
  "xep_0461", # Message replies
926
+ "xep_0469", # Bookmark Pinning
916
927
  "xep_0490", # Message Displayed Synchronization
928
+ "xep_0492", # Chat Notification Settings
917
929
  ]
918
930
 
919
931
  LOG_STRIP_ELEMENTS = ["data", "binval"]
@@ -178,6 +178,7 @@ class AttachmentMixin(TextMessageMixin):
178
178
  file_path = temp_dir / file_name
179
179
  if file_url:
180
180
  async with self.session.http.get(file_url) as r:
181
+ r.raise_for_status()
181
182
  with file_path.open("wb") as f:
182
183
  f.write(await r.read())
183
184
 
@@ -183,7 +183,7 @@ class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
183
183
  warnings.warn(
184
184
  "Slidge does not have privileges to send message on behalf of"
185
185
  " user.Refer to"
186
- " https://slidge.codeberg.page/docs/main/admin/privilege.html"
186
+ " https://slidge.im/docs/slidge/main/admin/privilege.html"
187
187
  " for more info."
188
188
  )
189
189
 
@@ -21,9 +21,9 @@ class ReactionRecipientMixin:
21
21
  form["type"] = "result"
22
22
  form.add_field("FORM_TYPE", "hidden", value="urn:xmpp:reactions:0:restrictions")
23
23
  if self.REACTIONS_SINGLE_EMOJI:
24
- form.add_field("max_reactions_per_user", value="1")
24
+ form.add_field("max_reactions_per_user", value="1", type="number")
25
25
  if available:
26
- form.add_field("allowlist", value=list(available))
26
+ form.add_field("allowlist", value=list(available), type="text-multi")
27
27
  return form
28
28
 
29
29
  async def available_emojis(
@@ -207,7 +207,8 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
207
207
  ) -> PepAvatar:
208
208
  if stanza.get_to() == self.xmpp.boundjid.bare:
209
209
  item = PepAvatar()
210
- item.set_avatar_from_cache(avatar_cache.get_by_pk(self.xmpp.avatar_pk))
210
+ if hasattr(self.xmpp, "avatar_pk"):
211
+ item.set_avatar_from_cache(avatar_cache.get_by_pk(self.xmpp.avatar_pk))
211
212
  return item
212
213
 
213
214
  if contact is None:
@@ -14,6 +14,7 @@ from multidict import CIMultiDictProxy
14
14
  from PIL.Image import Image
15
15
  from PIL.Image import open as open_image
16
16
  from sqlalchemy import select
17
+ from sqlalchemy.orm.exc import DetachedInstanceError
17
18
 
18
19
  from slidge.core import config
19
20
  from slidge.db.models import Avatar
@@ -102,6 +103,7 @@ class AvatarCache:
102
103
  if response.status == HTTPStatus.NOT_MODIFIED:
103
104
  log.debug("Using avatar cache for %s", url)
104
105
  raise NotModified
106
+ response.raise_for_status()
105
107
  return (
106
108
  open_image(io.BytesIO(await response.read())),
107
109
  response.headers,
@@ -141,7 +143,24 @@ class AvatarCache:
141
143
  )
142
144
  except NotModified:
143
145
  assert stored is not None
144
- return CachedAvatar.from_store(stored, self.dir)
146
+ try:
147
+ return CachedAvatar.from_store(stored, self.dir)
148
+ except DetachedInstanceError:
149
+ # This is an awful hack to prevent errors on startup under certain conditions,
150
+ # because we basically misused SQLAlchemy pretty bad in slidge.db.store.EngineMixin.session().
151
+ # cf https://codeberg.org/slidge/slidge/issues/36
152
+ # and https://docs.sqlalchemy.org/en/20/orm/session_basics.html#session-faq-threadsafe
153
+ # It may be related to threads as we only have reports of this for slidge-whatsapp and skidge
154
+ # which are the only implementations that uses threads.
155
+ # In any case, a proper fix implies a major refactoring in which we spawn and close SQLAlchemy
156
+ # "ORM Session"s with a reasonable, well-thought lifetime, instead of how we do it now, where we
157
+ # basically just brute-forced our way into having something usable but with poor performance.
158
+ # Databases, asyncio, and concurrency in general are hard… :(
159
+ # Oh, and getting rid of the convoluted mess that this giant method is would also probably
160
+ # be a good idea.
161
+ stored = self.store.get_by_url(avatar)
162
+ assert stored is not None
163
+ return CachedAvatar.from_store(stored, self.dir)
145
164
  else:
146
165
  img = await self._get_image(avatar)
147
166
  response_headers = None
@@ -58,6 +58,8 @@ class EngineMixin:
58
58
  def __init__(self, engine: Engine):
59
59
  self._engine = engine
60
60
 
61
+ # TODO: we should not have a global Session object but instead build Sessions with different parameters
62
+ # depending on the context (startup, incoming XMPP event, incoming legacy event).
61
63
  @contextmanager
62
64
  def session(self, **session_kwargs) -> Iterator[Session]:
63
65
  global _session
@@ -70,6 +70,7 @@ class LegacyParticipant(
70
70
  is_system=False,
71
71
  role: MucRole = "participant",
72
72
  affiliation: MucAffiliation = "member",
73
+ resource: str | None = None,
73
74
  ):
74
75
  self.session = session = muc.session
75
76
  self.xmpp = session.xmpp
@@ -83,7 +84,13 @@ class LegacyParticipant(
83
84
 
84
85
  self._nickname = nickname
85
86
 
86
- self.__update_jid(nickname)
87
+ if resource is None:
88
+ self.__update_jid(nickname)
89
+ else:
90
+ self._nickname_no_illegal = resource
91
+ self.jid = JID(self.muc.jid)
92
+ self.jid.resource = resource
93
+
87
94
  log.debug("Instantiation of: %r", self)
88
95
 
89
96
  self.contact: Optional["LegacyContact"] = None
@@ -510,6 +517,7 @@ class LegacyParticipant(
510
517
  stored.nickname,
511
518
  role=stored.role,
512
519
  affiliation=stored.affiliation,
520
+ resource=stored.resource,
513
521
  )
514
522
  part.pk = stored.id
515
523
  if contact is not None:
@@ -26,6 +26,7 @@ from ..core.mixins.disco import ChatterDiscoMixin
26
26
  from ..core.mixins.lock import NamedLockMixin
27
27
  from ..core.mixins.recipient import ReactionRecipientMixin, ThreadRecipientMixin
28
28
  from ..db.models import Room
29
+ from ..slixfix.xep_0492.stanza import WhenLiteral
29
30
  from ..util import ABCSubclassableOnceAtMost
30
31
  from ..util.types import (
31
32
  HoleBound,
@@ -994,7 +995,14 @@ class LegacyMUC(
994
995
  p["muc"]["status_codes"] = {110, 333}
995
996
  p.send()
996
997
 
997
- async def add_to_bookmarks(self, auto_join=True, invite=False, preserve=True):
998
+ async def add_to_bookmarks(
999
+ self,
1000
+ auto_join=True,
1001
+ invite=False,
1002
+ preserve=True,
1003
+ pin: bool | None = None,
1004
+ notify: WhenLiteral | None = None,
1005
+ ):
998
1006
  """
999
1007
  Add the MUC to the user's XMPP bookmarks (:xep:`0402')
1000
1008
 
@@ -1012,6 +1020,11 @@ class LegacyMUC(
1012
1020
  settings.
1013
1021
  :param preserve: preserve auto-join and bookmarks extensions
1014
1022
  set by the user outside slidge
1023
+ :param pin: Pin the group chat bookmark :xep:`0469`. Requires privileged entity.
1024
+ If set to ``None`` (default), the bookmark pinning status will be untouched.
1025
+ :param notify: Chat notification setting: :xep:`0492`. Requires privileged entity.
1026
+ If set to ``None`` (default), the setting will be untouched. Only the "global"
1027
+ notification setting is supported (ie, per client type is not possible).
1015
1028
  """
1016
1029
  item = Item()
1017
1030
  item["id"] = self.jid
@@ -1046,6 +1059,13 @@ class LegacyMUC(
1046
1059
  item["conference"]["autojoin"] = auto_join
1047
1060
 
1048
1061
  item["conference"]["nick"] = self.user_nick
1062
+
1063
+ if pin is not None:
1064
+ item["conference"]["extensions"]["pinned"] = pin
1065
+
1066
+ if notify is not None:
1067
+ item["conference"]["extensions"]["notify"].configure(notify)
1068
+
1049
1069
  iq = Iq(stype="set", sfrom=self.user_jid, sto=self.user_jid)
1050
1070
  iq["pubsub"]["publish"]["node"] = self.xmpp["xep_0402"].stanza.NS
1051
1071
  iq["pubsub"]["publish"].append(item)