slidge 0.2.8__tar.gz → 0.2.9__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 (211) hide show
  1. {slidge-0.2.8 → slidge-0.2.9}/.gitignore +1 -0
  2. {slidge-0.2.8 → slidge-0.2.9}/.woodpecker/container-ci.yaml +13 -9
  3. slidge-0.2.9/.woodpecker/docs.yaml +22 -0
  4. {slidge-0.2.8 → slidge-0.2.9}/.woodpecker/package.yaml +6 -9
  5. {slidge-0.2.8 → slidge-0.2.9}/.woodpecker/test.yaml +12 -13
  6. slidge-0.2.9/Dockerfile +43 -0
  7. slidge-0.2.9/PKG-INFO +134 -0
  8. slidge-0.2.9/dev/confs/slidge-dev.ini +8 -0
  9. slidge-0.2.9/dev/hot-reload.sh +8 -0
  10. slidge-0.2.9/docker-compose.yml +20 -0
  11. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/attachments.rst +1 -1
  12. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/config/index.rst +1 -1
  13. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/daemon.rst +2 -2
  14. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/register.rst +4 -0
  15. {slidge-0.2.8 → slidge-0.2.9}/pyproject.toml +5 -9
  16. {slidge-0.2.8 → slidge-0.2.9}/slidge/__init__.py +8 -0
  17. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/admin.py +3 -3
  18. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/gateway.py +1 -0
  19. {slidge-0.2.8 → slidge-0.2.9}/slidge/group/room.py +5 -2
  20. {slidge-0.2.8 → slidge-0.2.9}/slidge/main.py +3 -3
  21. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/types.py +1 -7
  22. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/util.py +0 -13
  23. slidge-0.2.9/slidge.egg-info/PKG-INFO +134 -0
  24. {slidge-0.2.8 → slidge-0.2.9}/slidge.egg-info/SOURCES.txt +2 -3
  25. {slidge-0.2.8 → slidge-0.2.9}/uv.lock +495 -448
  26. slidge-0.2.8/.woodpecker/container-cache.yml +0 -71
  27. slidge-0.2.8/.woodpecker/container.yml +0 -49
  28. slidge-0.2.8/.woodpecker/docs.yaml +0 -24
  29. slidge-0.2.8/Dockerfile +0 -94
  30. slidge-0.2.8/PKG-INFO +0 -793
  31. slidge-0.2.8/docker-compose.yml +0 -69
  32. slidge-0.2.8/slidge/__version__.py +0 -5
  33. slidge-0.2.8/slidge.egg-info/PKG-INFO +0 -793
  34. {slidge-0.2.8 → slidge-0.2.9}/.pre-commit-config.yaml +0 -0
  35. {slidge-0.2.8 → slidge-0.2.9}/LICENSE +0 -0
  36. {slidge-0.2.8 → slidge-0.2.9}/README.md +0 -0
  37. {slidge-0.2.8 → slidge-0.2.9}/commitlint.config.js +0 -0
  38. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/5x5.png +0 -0
  39. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/slidge-color-small.png +0 -0
  40. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/slidge-color.png +0 -0
  41. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/slidge-mono-black.png +0 -0
  42. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/slidge-mono-white.png +0 -0
  43. {slidge-0.2.8 → slidge-0.2.9}/dev/assets/slidge.svg +0 -0
  44. {slidge-0.2.8 → slidge-0.2.9}/dev/confs/movim.env +0 -0
  45. {slidge-0.2.8 → slidge-0.2.9}/dev/confs/nginx.conf +0 -0
  46. {slidge-0.2.8 → slidge-0.2.9}/dev/confs/slidge-example.ini +0 -0
  47. {slidge-0.2.8 → slidge-0.2.9}/dev/prettify_tests.py +0 -0
  48. {slidge-0.2.8 → slidge-0.2.9}/doap.xml +0 -0
  49. {slidge-0.2.8 → slidge-0.2.9}/docs/Makefile +0 -0
  50. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/component.rst +0 -0
  51. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/examples/ejabberd.yaml +0 -0
  52. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/examples/index.rst +0 -0
  53. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/examples/prosody.cfg.lua +0 -0
  54. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/index.rst +0 -0
  55. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/install.rst +0 -0
  56. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/note.rst +0 -0
  57. {slidge-0.2.8 → slidge-0.2.9}/docs/source/admin/privilege.rst +0 -0
  58. {slidge-0.2.8 → slidge-0.2.9}/docs/source/codeberg.svg +0 -0
  59. {slidge-0.2.8 → slidge-0.2.9}/docs/source/conf.py +0 -0
  60. {slidge-0.2.8 → slidge-0.2.9}/docs/source/dev/contributing.rst +0 -0
  61. {slidge-0.2.8 → slidge-0.2.9}/docs/source/dev/design.rst +0 -0
  62. {slidge-0.2.8 → slidge-0.2.9}/docs/source/dev/howto.rst +0 -0
  63. {slidge-0.2.8 → slidge-0.2.9}/docs/source/dev/index.rst +0 -0
  64. {slidge-0.2.8 → slidge-0.2.9}/docs/source/dev/tutorial.rst +0 -0
  65. {slidge-0.2.8 → slidge-0.2.9}/docs/source/glossary.rst +0 -0
  66. {slidge-0.2.8 → slidge-0.2.9}/docs/source/index.rst +0 -0
  67. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/commands.rst +0 -0
  68. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/contacts.rst +0 -0
  69. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/foxyproxy.png +0 -0
  70. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/gajim.png +0 -0
  71. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/index.rst +0 -0
  72. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/low_profile.rst +0 -0
  73. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/movim1.png +0 -0
  74. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/movim2.png +0 -0
  75. {slidge-0.2.8 → slidge-0.2.9}/docs/source/user/note.rst +0 -0
  76. {slidge-0.2.8 → slidge-0.2.9}/setup.cfg +0 -0
  77. {slidge-0.2.8 → slidge-0.2.9}/slidge/__main__.py +0 -0
  78. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/__init__.py +0 -0
  79. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/adhoc.py +0 -0
  80. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/base.py +0 -0
  81. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/categories.py +0 -0
  82. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/chat_command.py +0 -0
  83. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/register.py +0 -0
  84. {slidge-0.2.8 → slidge-0.2.9}/slidge/command/user.py +0 -0
  85. {slidge-0.2.8 → slidge-0.2.9}/slidge/contact/__init__.py +0 -0
  86. {slidge-0.2.8 → slidge-0.2.9}/slidge/contact/contact.py +0 -0
  87. {slidge-0.2.8 → slidge-0.2.9}/slidge/contact/roster.py +0 -0
  88. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/__init__.py +0 -0
  89. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/config.py +0 -0
  90. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/__init__.py +0 -0
  91. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/caps.py +0 -0
  92. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/disco.py +0 -0
  93. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/message/__init__.py +0 -0
  94. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/message/chat_state.py +0 -0
  95. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/message/marker.py +0 -0
  96. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/message/message.py +0 -0
  97. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/__init__.py +0 -0
  98. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/admin.py +0 -0
  99. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/mam.py +0 -0
  100. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/misc.py +0 -0
  101. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/owner.py +0 -0
  102. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/muc/ping.py +0 -0
  103. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/presence.py +0 -0
  104. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/registration.py +0 -0
  105. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/search.py +0 -0
  106. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/session_dispatcher.py +0 -0
  107. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/util.py +0 -0
  108. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/dispatcher/vcard.py +0 -0
  109. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/__init__.py +0 -0
  110. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/attachment.py +0 -0
  111. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/avatar.py +0 -0
  112. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/base.py +0 -0
  113. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/db.py +0 -0
  114. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/disco.py +0 -0
  115. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/lock.py +0 -0
  116. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/message.py +0 -0
  117. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/message_maker.py +0 -0
  118. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/message_text.py +0 -0
  119. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/presence.py +0 -0
  120. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/mixins/recipient.py +0 -0
  121. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/pubsub.py +0 -0
  122. {slidge-0.2.8 → slidge-0.2.9}/slidge/core/session.py +2 -2
  123. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/__init__.py +0 -0
  124. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/__init__.py +0 -0
  125. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/env.py +0 -0
  126. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/script.py.mako +0 -0
  127. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/04cf35e3cf85_add_participant_nickname_no_illegal.py +0 -0
  128. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
  129. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -0
  130. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
  131. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
  132. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
  133. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
  134. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -0
  135. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
  136. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
  137. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
  138. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
  139. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
  140. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
  141. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
  142. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
  143. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
  144. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
  145. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/avatar.py +0 -0
  146. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/meta.py +0 -0
  147. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/models.py +0 -0
  148. {slidge-0.2.8 → slidge-0.2.9}/slidge/db/store.py +0 -0
  149. {slidge-0.2.8 → slidge-0.2.9}/slidge/group/__init__.py +0 -0
  150. {slidge-0.2.8 → slidge-0.2.9}/slidge/group/archive.py +0 -0
  151. {slidge-0.2.8 → slidge-0.2.9}/slidge/group/bookmarks.py +0 -0
  152. {slidge-0.2.8 → slidge-0.2.9}/slidge/group/participant.py +0 -0
  153. {slidge-0.2.8 → slidge-0.2.9}/slidge/migration.py +0 -0
  154. {slidge-0.2.8 → slidge-0.2.9}/slidge/py.typed +0 -0
  155. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/__init__.py +0 -0
  156. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/delivery_receipt.py +0 -0
  157. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/link_preview/__init__.py +0 -0
  158. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/link_preview/link_preview.py +0 -0
  159. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/link_preview/stanza.py +0 -0
  160. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/roster.py +0 -0
  161. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0077/__init__.py +0 -0
  162. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0077/register.py +0 -0
  163. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0077/stanza.py +0 -0
  164. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0100/__init__.py +0 -0
  165. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0100/gateway.py +0 -0
  166. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0100/stanza.py +0 -0
  167. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0153/__init__.py +0 -0
  168. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
  169. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0292/__init__.py +0 -0
  170. {slidge-0.2.8 → slidge-0.2.9}/slidge/slixfix/xep_0292/vcard4.py +0 -0
  171. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/__init__.py +0 -0
  172. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/archive_msg.py +0 -0
  173. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/conf.py +0 -0
  174. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/jid_escaping.py +0 -0
  175. {slidge-0.2.8 → slidge-0.2.9}/slidge/util/test.py +0 -0
  176. {slidge-0.2.8 → slidge-0.2.9}/slidge.egg-info/dependency_links.txt +0 -0
  177. {slidge-0.2.8 → slidge-0.2.9}/slidge.egg-info/entry_points.txt +0 -0
  178. {slidge-0.2.8 → slidge-0.2.9}/slidge.egg-info/requires.txt +0 -0
  179. {slidge-0.2.8 → slidge-0.2.9}/slidge.egg-info/top_level.txt +0 -0
  180. {slidge-0.2.8 → slidge-0.2.9}/superduper/__init__.py +0 -0
  181. {slidge-0.2.8 → slidge-0.2.9}/superduper/contact.py +0 -0
  182. {slidge-0.2.8 → slidge-0.2.9}/superduper/gateway.py +0 -0
  183. {slidge-0.2.8 → slidge-0.2.9}/superduper/group.py +0 -0
  184. {slidge-0.2.8 → slidge-0.2.9}/superduper/legacy_client.py +0 -0
  185. {slidge-0.2.8 → slidge-0.2.9}/superduper/session.py +0 -0
  186. {slidge-0.2.8 → slidge-0.2.9}/superduper/util.py +0 -0
  187. {slidge-0.2.8 → slidge-0.2.9}/tests/conftest.py +0 -0
  188. {slidge-0.2.8 → slidge-0.2.9}/tests/test_adhoc/test_access.py +0 -0
  189. {slidge-0.2.8 → slidge-0.2.9}/tests/test_adhoc/test_confirmation.py +0 -0
  190. {slidge-0.2.8 → slidge-0.2.9}/tests/test_adhoc/test_form.py +0 -0
  191. {slidge-0.2.8 → slidge-0.2.9}/tests/test_adhoc/test_reported.py +0 -0
  192. {slidge-0.2.8 → slidge-0.2.9}/tests/test_attachment.py +0 -0
  193. {slidge-0.2.8 → slidge-0.2.9}/tests/test_avatar.py +0 -0
  194. {slidge-0.2.8 → slidge-0.2.9}/tests/test_backfill.py +0 -0
  195. {slidge-0.2.8 → slidge-0.2.9}/tests/test_chat_commands.py +0 -0
  196. {slidge-0.2.8 → slidge-0.2.9}/tests/test_config.py +0 -0
  197. {slidge-0.2.8 → slidge-0.2.9}/tests/test_db/test_store.py +0 -0
  198. {slidge-0.2.8 → slidge-0.2.9}/tests/test_db/test_user.py +0 -0
  199. {slidge-0.2.8 → slidge-0.2.9}/tests/test_feature_restriction.py +0 -0
  200. {slidge-0.2.8 → slidge-0.2.9}/tests/test_mam_archivable.py +0 -0
  201. {slidge-0.2.8 → slidge-0.2.9}/tests/test_mds.py +0 -0
  202. {slidge-0.2.8 → slidge-0.2.9}/tests/test_muc.py +0 -0
  203. {slidge-0.2.8 → slidge-0.2.9}/tests/test_name_in_constructor.py +0 -0
  204. {slidge-0.2.8 → slidge-0.2.9}/tests/test_resourceprep.py +0 -0
  205. {slidge-0.2.8 → slidge-0.2.9}/tests/test_session.py +0 -0
  206. {slidge-0.2.8 → slidge-0.2.9}/tests/test_session_2.py +0 -0
  207. {slidge-0.2.8 → slidge-0.2.9}/tests/test_set_name_before_fill.py +0 -0
  208. {slidge-0.2.8 → slidge-0.2.9}/tests/test_shakespeare.py +0 -0
  209. {slidge-0.2.8 → slidge-0.2.9}/tests/test_stanza_link_preview.py +0 -0
  210. {slidge-0.2.8 → slidge-0.2.9}/tests/test_util.py +0 -0
  211. {slidge-0.2.8 → slidge-0.2.9}/tests/test_vcard.py +0 -0
@@ -42,3 +42,4 @@ htmlcov
42
42
  /dev/slidge.sqlite
43
43
 
44
44
  .python-version
45
+ slidge/__version__.py
@@ -1,9 +1,12 @@
1
1
  # Build a container with a virtualenv that can be used for tests and to build docs.
2
2
 
3
3
  when:
4
- event: [ manual, cron ]
5
-
6
- depends_on: [ container-cache ]
4
+ event: [ push ]
5
+ branch: main
6
+ path:
7
+ - Dockerfile
8
+ - pyproject.toml
9
+ - uv.lock
7
10
 
8
11
  matrix:
9
12
  PYTHON_VERSION:
@@ -11,19 +14,20 @@ matrix:
11
14
  - "3.12"
12
15
  - "3.13"
13
16
 
17
+ labels:
18
+ platform: linux/amd64
19
+
14
20
  steps:
15
21
  build-and-push:
16
22
  image: woodpeckerci/plugin-docker-buildx
17
23
  settings:
18
- repo: codeberg.org/${CI_REPO_OWNER}/woodpecker-${CI_REPO_NAME}
24
+ repo: codeberg.org/slidge/slidge
19
25
  registry: codeberg.org
20
26
  build_args:
21
27
  PYTHONVER: "${PYTHON_VERSION}"
22
- tag: ${PYTHON_VERSION}
23
- target: woodpecker-${CI_REPO_NAME}
28
+ tag: ci-${PYTHON_VERSION}
29
+ target: ci
24
30
  username: slidge
25
31
  password:
26
32
  from_secret: CODEBERG_TOKEN
27
- cache_from: codeberg.org/slidge/slidge-builder:buildcache-base-amd64
28
- cache_images:
29
- - codeberg.org/slidge/woodpecker-slidge:buildcache-${PYTHON_VERSION}
33
+ cache_from: codeberg.org/slidge/slidge:buildcache
@@ -0,0 +1,22 @@
1
+ when:
2
+ event: [ push, tag ]
3
+ path: [ "slidge/**/*.py", "superduper/**/*.py", "docs/**/*" ]
4
+
5
+ labels:
6
+ platform: linux/amd64
7
+
8
+ steps:
9
+ build:
10
+ image: codeberg.org/slidge/slidge:ci-3.13
11
+ pull: true
12
+ commands:
13
+ - uv sync --all-groups --all-extras
14
+ - cd docs
15
+ - make html
16
+
17
+ publish:
18
+ image: codeberg.org/slidge/woodpecker-publish-pages
19
+ pull: true
20
+ settings:
21
+ token:
22
+ from_secret: CODEBERG_TOKEN
@@ -1,18 +1,19 @@
1
1
  # Build a source dist and a wheel.
2
2
 
3
3
  when:
4
- event: [ push, tag, pull_request ]
4
+ event: [ push, tag ]
5
5
  path: [ "slidge/**/*", "pyproject.toml", "uv.lock", "README.md" ]
6
+ branch: main
7
+
8
+ labels:
9
+ platform: linux/amd64
6
10
 
7
11
  # We do not need to build several packages for several python versions
8
12
  # since slidge is pure python.
9
13
  variables:
10
- - &image codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:3.13
14
+ - &image codeberg.org/slidge/slidge:ci-3.13
11
15
 
12
16
  steps:
13
- version:
14
- image: codeberg.org/slidge/woodpecker-version
15
-
16
17
  changelog:
17
18
  image: codeberg.org/slidge/woodpecker-generate-changelog
18
19
  pull: true
@@ -23,8 +24,6 @@ steps:
23
24
  - uv build
24
25
 
25
26
  codeberg-pypi:
26
- when:
27
- event: [ push, tag ]
28
27
  image: *image
29
28
  environment:
30
29
  CODEBERG_TOKEN:
@@ -34,7 +33,6 @@ steps:
34
33
 
35
34
  pypi:
36
35
  when:
37
- branch: main
38
36
  event: tag
39
37
  image: *image
40
38
  environment:
@@ -45,7 +43,6 @@ steps:
45
43
 
46
44
  codeberg-release:
47
45
  when:
48
- branch: main
49
46
  event: tag
50
47
  image: woodpeckerci/plugin-release
51
48
  settings:
@@ -8,7 +8,11 @@ matrix:
8
8
  - "3.12"
9
9
  - "3.13"
10
10
 
11
+ labels:
12
+ platform: linux/amd64
13
+
11
14
  variables:
15
+ - &ci-image codeberg.org/slidge/slidge:ci-${PYTHON_VERSION}
12
16
  - &only-once
13
17
  when:
14
18
  matrix:
@@ -16,44 +20,39 @@ variables:
16
20
  event: push
17
21
 
18
22
  steps:
19
- # This is often a no-op, but since we manually build the woodpecker-slidge:3.x images,
20
- # their venv may be out of date, even if uv.lock is not modified.
21
23
  update-venv:
22
- image: codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:${PYTHON_VERSION}
24
+ image: *ci-image
23
25
  pull: true
24
26
  commands:
25
- - cp -r /venv .venv
26
- - uv venv --allow-existing .venv
27
- - uv export > req.txt
28
- - uv pip install --requirements req.txt
27
+ - uv sync --all-groups --all-extras
29
28
 
30
29
  ruff:
31
- image: codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:${PYTHON_VERSION}
30
+ image: *ci-image
32
31
  commands:
33
32
  - ruff check
34
33
  - ruff format --check
35
34
 
36
35
  mypy:
37
- image: codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:${PYTHON_VERSION}
36
+ image: *ci-image
38
37
  commands:
39
38
  - mypy
40
39
 
41
40
  test:
42
- image: codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:${PYTHON_VERSION}
41
+ image: *ci-image
43
42
  commands:
44
43
  - coverage run -m pytest tests
45
44
  - coverage report | tee coverage.txt
46
45
  - coverage html
47
46
 
48
- badge:
49
- image: codeberg.org/slidge/woodpecker-${CI_REPO_NAME}:${PYTHON_VERSION}
47
+ coverage-badge:
48
+ image: *ci-image
50
49
  commands:
51
50
  - uv pip install pybadges
52
51
  - COVERAGE=$(tail -n1 coverage.txt | awk 'NF>1{print $NF}')
53
52
  - python -m pybadges --left-text=coverage --right-text=$COVERAGE --right-color=green > htmlcov/coverage.svg || true
54
53
  <<: *only-once
55
54
 
56
- publish:
55
+ coverage-publish:
57
56
  image: codeberg.org/slidge/woodpecker-publish-pages
58
57
  pull: true
59
58
  settings:
@@ -0,0 +1,43 @@
1
+ ARG PYTHONVER=3.13
2
+ ARG DISTRO=bookworm-slim
3
+
4
+ ## Install dependencies in a virtual env
5
+ FROM ghcr.io/astral-sh/uv:python$PYTHONVER-$DISTRO AS builder
6
+ ENV UV_PROJECT_ENVIRONMENT=/venv
7
+ RUN uv venv $UV_PROJECT_ENVIRONMENT
8
+ COPY uv.lock pyproject.toml .
9
+ RUN uv sync --all-groups --all-extras --no-install-project
10
+
11
+ ## CI environment for slidge, where we move /venv to .venv
12
+ FROM ghcr.io/astral-sh/uv:python$PYTHONVER-$DISTRO AS ci
13
+ ENV UV_LINK_MODE=copy
14
+ ENV UV_PROJECT_ENVIRONMENT=/woodpecker/src/codeberg.org/slidge/slidge/.venv
15
+ ENV PATH="$UV_PROJECT_ENVIRONMENT/bin:$PATH"
16
+ RUN apt-get update -y && \
17
+ apt-get install -y --no-install-recommends \
18
+ git \
19
+ make \
20
+ && rm -rf /var/lib/apt/lists/*
21
+ COPY --from=builder /root/.cache /root/.cache
22
+
23
+ ## Dev container
24
+ FROM builder AS dev
25
+ ENV PATH="/venv/bin:$PATH"
26
+ ENV PYTHONUNBUFFERED=1
27
+ # libmagic1: to guess mime type from files
28
+ # media-types: to determine file name suffix based on file type
29
+ RUN apt-get update -y && \
30
+ apt-get install -y --no-install-recommends \
31
+ libmagic1 \
32
+ media-types \
33
+ shared-mime-info \
34
+ && rm -rf /var/lib/apt/lists/*
35
+ # prosody certificate for localhost
36
+ COPY --from=codeberg.org/slidge/prosody-slidge-dev:latest \
37
+ /etc/prosody/certs/localhost.crt \
38
+ /usr/local/share/ca-certificates/
39
+ RUN update-ca-certificates
40
+ RUN pip install watchdog[watchmedo]
41
+ WORKDIR /io
42
+ COPY ./dev/hot-reload.sh .
43
+ ENTRYPOINT ["./hot-reload.sh"]
slidge-0.2.9/PKG-INFO ADDED
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: slidge
3
+ Version: 0.2.9
4
+ Summary: XMPP bridging framework
5
+ Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
6
+ License-Expression: AGPL-3.0-or-later
7
+ Project-URL: Homepage, https://codeberg.org/slidge/
8
+ Project-URL: Issues, https://codeberg.org/slidge/slidge/issues
9
+ Project-URL: Repository, https://codeberg.org/slidge/slidge/
10
+ Project-URL: Chat room, https://conference.nicoco.fr:5281/muc_log/slidge/
11
+ Project-URL: Documentation, https://slidge.im/docs/slidge/main
12
+ Project-URL: changelog, https://codeberg.org/slidge/slidge/releases
13
+ Keywords: xmpp,gateway,bridge,instant messaging
14
+ Classifier: Topic :: Internet :: XMPP
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: >=3.11
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: aiohttp[speedups]<4,>=3.11.11
20
+ Requires-Dist: alembic<2,>=1.14.0
21
+ Requires-Dist: configargparse<2,>=1.7
22
+ Requires-Dist: defusedxml>=0.7.1
23
+ Requires-Dist: pillow<12,>=11.0.0
24
+ Requires-Dist: python-magic<0.5,>=0.4.27
25
+ Requires-Dist: qrcode<9,>=8.0
26
+ Requires-Dist: slixmpp<2,>=1.9.0
27
+ Requires-Dist: sqlalchemy<3,>=2
28
+ Requires-Dist: thumbhash>=0.1.2
29
+ Dynamic: license-file
30
+
31
+ ![Slidge logo](https://codeberg.org/slidge/slidge/raw/branch/main/dev/assets/slidge-color-small.png)
32
+
33
+ [![Chat](https://conference.nicoco.fr:5281/muc_badge/slidge@conference.nicoco.fr)](https://conference.nicoco.fr:5281/muc_log/slidge/)
34
+
35
+
36
+ [![woodpecker CI status](https://ci.codeberg.org/api/badges/14027/status.svg)](https://ci.codeberg.org/repos/14027)
37
+ [![coverage](https://slidge.im/coverage/main/coverage.svg)](https://slidge.im/coverage/main)
38
+
39
+ [![pypi version](https://badge.fury.io/py/slidge.svg)](https://pypi.org/project/slidge/)
40
+ [![debian unstable version](https://badges.debian.net/badges/debian/unstable/python3-slidge/version.svg)](https://packages.debian.org/unstable/python3-slidge)
41
+
42
+ Slidge is an XMPP (puppeteer) gateway library in python.
43
+ It makes
44
+ [writing gateways to other chat networks](https://slidge.im/docs/slidge/main/dev/tutorial.html)
45
+ (*legacy modules*) as frictionless as possible.
46
+ It supports fancy IM features, such as
47
+ [(emoji) reactions](https://xmpp.org/extensions/xep-0444.html),
48
+ [replies](https://xmpp.org/extensions/xep-0461.html), and
49
+ [retractions](https://xmpp.org/extensions/xep-0424.html).
50
+ The full list of supported XEPs in on [xmpp.org](https://xmpp.org/software/slidge/).
51
+
52
+ Status
53
+ ------
54
+
55
+ Slidge is **beta**-grade software. It support groups and 1:1 chats.
56
+ Try slidge and give us some
57
+ feedback, through the [MUC](xmpp:slidge@conference.nicoco.fr?join) or the
58
+ [issue tracker](https://codeberg.org/slidge/slidge/issues).
59
+ Don't be shy!
60
+
61
+ Usage
62
+ -----
63
+
64
+ A minimal (and fictional!) slidge-powered "legacy module" looks like this:
65
+
66
+ ```python
67
+ from cool_chat_lib import CoolClient
68
+ from slidge import BaseGateway, BaseSession
69
+ from slidge.contact import LegacyContact
70
+ from slidge.group import LegacyMUC
71
+ from slidge.db import GatewayUser
72
+
73
+
74
+ class Gateway(BaseGateway):
75
+ # Various aspects of the gateway component are configured as class
76
+ # attributes of the concrete Gateway class
77
+ COMPONENT_NAME = "Gateway to the super duper chat network"
78
+
79
+
80
+ class Session(BaseSession):
81
+ def __init__(self, user: GatewayUser):
82
+ super().__init__(user)
83
+ self.legacy_client = CoolClient(
84
+ login=user.legacy_module_data["username"],
85
+ password=user.legacy_module_data["password"],
86
+ )
87
+
88
+ async def on_text(self, chat: LegacyContact | LegacyMUC, text: str, **kwargs):
89
+ """
90
+ Triggered when the slidge user sends an XMPP message through the gateway
91
+ """
92
+ self.legacy_client.send_message(text=text, destination=chat.legacy_id)
93
+ ```
94
+
95
+ There's more in [the tutorial](https://slidge.im/docs/slidge/main/dev/tutorial.html)!
96
+
97
+ Installation
98
+ ------------
99
+
100
+ ⚠️ Slidge is a lib for gateway developers, if you are an XMPP server admin and
101
+ want to install gateways on your server, you are looking for a
102
+ [slidge-based gateway](https://codeberg.org/explore/repos?q=slidge&topic=1).
103
+ or the
104
+ [slidge-debian](https://git.sr.ht/~nicoco/slidge-debian)
105
+ bundle.
106
+
107
+ Slidge is available on
108
+ [codeberg](https://codeberg.org/slidge/-/packages) (python packages and containers)
109
+ and [pypi](https://pypi.org/project/slidge/).
110
+ Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
111
+
112
+ About privacy
113
+ -------------
114
+
115
+ Slidge (and most if not all XMPP gateway that I know of) will break
116
+ end-to-end encryption, or more precisely one of the 'ends' become the
117
+ gateway itself. If privacy is a major concern for you, my advice would
118
+ be to:
119
+
120
+ - use XMPP + OMEMO
121
+ - self-host your gateways
122
+ - have your gateways hosted by someone you know AFK and trust
123
+
124
+ Related projects
125
+ ----------------
126
+
127
+ - [Spectrum](https://www.spectrum.im/)
128
+ - [telegabber](https://dev.narayana.im/narayana/telegabber)
129
+ - [biboumi](https://biboumi.louiz.org/)
130
+ - [Bifröst](https://github.com/matrix-org/matrix-bifrost)
131
+ - [Mautrix](https://github.com/mautrix)
132
+ - [matterbridge](https://github.com/42wim/matterbridge)
133
+
134
+ Thank you, [Trung](https://trung.fun/), for the slidge logo!
@@ -0,0 +1,8 @@
1
+ legacy-module=superduper
2
+ jid=slidge.localhost
3
+ secret=secret
4
+ server=localhost
5
+ upload-service=upload.localhost
6
+ admins=test@localhost
7
+ debug=true
8
+ dev-mode=true
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+
3
+ watchmedo auto-restart \
4
+ --pattern *.py \
5
+ --directory /io/superduper \
6
+ --directory /io/slidge \
7
+ --recursive \
8
+ python -- -m slidge -c /etc/slidge/slidge.ini
@@ -0,0 +1,20 @@
1
+ services:
2
+ superduper:
3
+ build:
4
+ context: .
5
+ target: dev
6
+ network_mode: service:prosody
7
+ volumes:
8
+ - ./slidge:/io/slidge
9
+ - ./superduper:/io/superduper
10
+ - ./dev/assets:/io/superduper/assets
11
+ - ./persistent:/var/lib/slidge/slidge.localhost
12
+ - ./dev/confs/slidge-dev.ini:/etc/slidge/slidge.ini
13
+ depends_on:
14
+ - prosody
15
+
16
+ prosody:
17
+ image: codeberg.org/slidge/prosody-slidge-dev:latest
18
+ ports:
19
+ - "127.0.0.1:5281:5281" # prosody's https://...
20
+ - "127.0.0.1:5222:5222" # XMPP
@@ -88,7 +88,7 @@ Cons:
88
88
  Example 1: prosody's mod_http_file_share
89
89
  ----------------------------------------
90
90
 
91
- In slidge's config: ``upload-service=example.org``
91
+ In slidge's config: ``upload-service=upload.example.org``
92
92
 
93
93
  .. code-block:: lua
94
94
 
@@ -4,7 +4,7 @@ Configuration
4
4
  .. include:: ../note.rst
5
5
 
6
6
  .. note::
7
- For the debian package, just edit the ``/etc/slidge/conf.d/common.conf`` and
7
+ For the debian unofficial package, just edit the ``/etc/slidge/conf.d/common.conf`` and
8
8
  ``/etc/slidge/*.conf`` files, and use :ref:`Debian packages (systemd)` to
9
9
  launch slidge.
10
10
 
@@ -76,10 +76,10 @@ Give permission for this user to use subuids and subgids (as root, required for
76
76
 
77
77
  .. code-block:: bash
78
78
 
79
- usermod --add-subuids 200000-201000 --add-subgids 200000-201000 slidge
79
+ usermod --add-subuids 200000-210000 --add-subgids 200000-210000 slidge
80
80
 
81
81
  .. warning::
82
- Check that the 200000-201000 range does not overlap with any other user's range
82
+ Check that the 200000-210000 range does not overlap with any other user's range
83
83
  in ``/etc/subuid`` and ``/etc/subgid``
84
84
 
85
85
  Enable lingering for this user so that its systemd user services start on startup (as root):
@@ -45,3 +45,7 @@ Other clients
45
45
 
46
46
  Other clients might have different UIs, but you can always fall back to the
47
47
  "register" :term:`Chatbot Command`.
48
+
49
+ In your XMPP client, start a new conversation with
50
+ JID ``superduper.example.org``.
51
+ Type "register" and follow the instructions.
@@ -17,22 +17,24 @@ dependencies = [
17
17
  authors = [
18
18
  {name = "Nicolas Cedilnik", email = "nicoco@nicoco.fr"},
19
19
  ]
20
- license = {file = "LICENSE"}
20
+ license = "AGPL-3.0-or-later"
21
21
  classifiers = [
22
22
  "Topic :: Internet :: XMPP",
23
23
  "Topic :: Software Development :: Libraries :: Python Modules",
24
24
  ]
25
25
  keywords = ["xmpp", "gateway", "bridge", "instant messaging"]
26
- version = "v0.2.8"
26
+ dynamic = ["version"]
27
27
  readme = "README.md"
28
28
 
29
29
  [build-system]
30
- requires = ["setuptools", "setuptools-scm"]
30
+ requires = ["setuptools>=64", "setuptools-scm>=8"]
31
31
  build-backend = "setuptools.build_meta"
32
32
 
33
33
  [tool.setuptools.packages.find]
34
34
  include = ["slidge*"]
35
35
 
36
+ [tool.setuptools_scm]
37
+
36
38
  [project.scripts]
37
39
  slidge = 'slidge.main:main'
38
40
 
@@ -111,12 +113,6 @@ name = "codeberg"
111
113
  url = "https://codeberg.org/api/packages/slidge/pypi/simple"
112
114
  publish-url = "https://codeberg.org/api/packages/slidge/pypi"
113
115
 
114
- [tool.setuptools]
115
- # FIXME: remove this when the setuptools upstream bug is fixed
116
- # https://github.com/astral-sh/uv/issues/9513#issuecomment-2519527822
117
- license-files = []
118
-
119
-
120
116
  [tool.git-cliff.remote.gitea]
121
117
  owner = "slidge"
122
118
  repo = "slidge"
@@ -6,6 +6,7 @@ Contains importable classes for a minimal function :term:`Legacy Module`.
6
6
 
7
7
  import sys
8
8
  import warnings
9
+ from importlib.metadata import PackageNotFoundError, version
9
10
 
10
11
  from . import slixfix # noqa: F401
11
12
  from .command import FormField, SearchResult # noqa: F401
@@ -37,8 +38,15 @@ def formatwarning(message, category, filename, lineno, line=""):
37
38
 
38
39
  warnings.formatwarning = formatwarning
39
40
 
41
+ try:
42
+ __version__ = version("slidge")
43
+ except PackageNotFoundError:
44
+ # package is not installed
45
+ __version__ = "dev"
46
+
40
47
 
41
48
  __all__ = [
49
+ "__version__",
42
50
  "BaseGateway",
43
51
  "BaseSession",
44
52
  # For backwards compatibility, these names are still importable from the
@@ -60,8 +60,6 @@ class SlidgeInfo(AdminCommand):
60
60
  ACCESS = CommandAccess.ANY
61
61
 
62
62
  async def run(self, _session, _ifrom, *_):
63
- from slidge.__version__ import __version__
64
-
65
63
  start = self.xmpp.datetime_started # type:ignore
66
64
  uptime = datetime.now() - start
67
65
 
@@ -100,8 +98,10 @@ class SlidgeInfo(AdminCommand):
100
98
  legacy_module = importlib.import_module(config.LEGACY_MODULE)
101
99
  version = getattr(legacy_module, "__version__", "No version")
102
100
 
101
+ import slidge
102
+
103
103
  return (
104
- f"{self.xmpp.COMPONENT_NAME} (slidge core {__version__},"
104
+ f"{self.xmpp.COMPONENT_NAME} (slidge core {slidge.__version__},"
105
105
  f" {config.LEGACY_MODULE} {version})\n"
106
106
  f"Up since {start:%Y-%m-%d %H:%M} ({ago} ago)"
107
107
  )
@@ -526,6 +526,7 @@ class BaseGateway(
526
526
  "You are not connected to this gateway! "
527
527
  f"Maybe this message will tell you why: {e}"
528
528
  )
529
+ session.logged = False
529
530
  return
530
531
 
531
532
  log.info("Login success for %s", session.user_jid)
@@ -1016,8 +1016,11 @@ class LegacyMUC(
1016
1016
  item = ans["pubsub"]["items"]["item"]
1017
1017
  item["id"] = self.jid
1018
1018
  return item
1019
- except (IqError, IqTimeout) as exc:
1020
- warnings.warn(f"Cannot fetch bookmark: {exc}")
1019
+ except IqTimeout as exc:
1020
+ warnings.warn(f"Cannot fetch bookmark for {self.user_jid}: timeout")
1021
+ return None
1022
+ except IqError as exc:
1023
+ warnings.warn(f"Cannot fetch bookmark for {self.user_jid}: {exc}")
1021
1024
  return None
1022
1025
  except PermissionError:
1023
1026
  warnings.warn(
@@ -24,8 +24,8 @@ from pathlib import Path
24
24
 
25
25
  import configargparse
26
26
 
27
+ import slidge
27
28
  from slidge import BaseGateway
28
- from slidge.__version__ import __version__
29
29
  from slidge.core import config
30
30
  from slidge.core.pubsub import PepAvatar, PepNick
31
31
  from slidge.db import SlidgeStore
@@ -96,7 +96,7 @@ def get_configurator():
96
96
  p.add_argument(
97
97
  "--version",
98
98
  action="version",
99
- version=f"%(prog)s {__version__}",
99
+ version=f"%(prog)s {slidge.__version__}",
100
100
  )
101
101
  configurator = MainConfig(config, p)
102
102
  return configurator
@@ -128,7 +128,7 @@ def main():
128
128
  signal.signal(signal.SIGTERM, handle_sigterm)
129
129
 
130
130
  unknown_argv = configure()
131
- logging.info("Starting slidge version %s", __version__)
131
+ logging.info("Starting slidge version %s", slidge.__version__)
132
132
 
133
133
  legacy_module = importlib.import_module(config.LEGACY_MODULE)
134
134
  logging.debug("Legacy module: %s", dir(legacy_module))
@@ -21,7 +21,7 @@ from typing import (
21
21
  )
22
22
 
23
23
  from slixmpp import Message, Presence
24
- from slixmpp.types import PresenceShows, PresenceTypes
24
+ from slixmpp.types import PresenceShows, PresenceTypes, ResourceDict
25
25
 
26
26
  if TYPE_CHECKING:
27
27
  from ..contact import LegacyContact
@@ -155,12 +155,6 @@ class MucType(IntEnum):
155
155
  PseudoPresenceShow = Union[PresenceShows, Literal[""]]
156
156
 
157
157
 
158
- class ResourceDict(TypedDict):
159
- show: PseudoPresenceShow
160
- status: str
161
- priority: int
162
-
163
-
164
158
  MessageOrPresenceTypeVar = TypeVar(
165
159
  "MessageOrPresenceTypeVar", bound=Union[Message, Presence]
166
160
  )
@@ -218,19 +218,6 @@ class SlidgeLogger(logging.Logger):
218
218
  log = logging.getLogger(__name__)
219
219
 
220
220
 
221
- def get_version() -> str:
222
- try:
223
- git = subprocess.check_output(
224
- ["git", "rev-parse", "HEAD"],
225
- stderr=subprocess.DEVNULL,
226
- cwd=Path(__file__).parent,
227
- ).decode()
228
- except (FileNotFoundError, subprocess.CalledProcessError):
229
- return "NO_VERSION"
230
- else:
231
- return "git-" + git[:10]
232
-
233
-
234
221
  def merge_resources(resources: dict[str, ResourceDict]) -> Optional[ResourceDict]:
235
222
  if len(resources) == 0:
236
223
  return None