slidge 0.2.9__tar.gz → 0.2.11__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.
- {slidge-0.2.9 → slidge-0.2.11}/PKG-INFO +9 -10
- {slidge-0.2.9 → slidge-0.2.11}/README.md +7 -8
- {slidge-0.2.9 → slidge-0.2.11}/pyproject.toml +1 -1
- {slidge-0.2.9 → slidge-0.2.11}/slidge/__init__.py +1 -2
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/gateway.py +5 -3
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/attachment.py +2 -2
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/pubsub.py +6 -2
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/store.py +1 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/group/participant.py +2 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/group/room.py +1 -1
- {slidge-0.2.9 → slidge-0.2.11}/slidge/main.py +12 -6
- slidge-0.2.11/slidge/slixfix/__init__.py +141 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/conf.py +14 -4
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/PKG-INFO +9 -10
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/SOURCES.txt +1 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/requires.txt +1 -1
- slidge-0.2.11/superduper/__main__.py +3 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_muc.py +3 -0
- {slidge-0.2.9 → slidge-0.2.11}/uv.lock +283 -280
- slidge-0.2.9/slidge/slixfix/__init__.py +0 -92
- {slidge-0.2.9 → slidge-0.2.11}/.gitignore +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/.pre-commit-config.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/.woodpecker/container-ci.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/.woodpecker/docs.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/.woodpecker/package.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/.woodpecker/test.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/Dockerfile +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/LICENSE +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/commitlint.config.js +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/5x5.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/slidge-color-small.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/slidge-color.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/slidge-mono-black.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/slidge-mono-white.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/assets/slidge.svg +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/confs/movim.env +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/confs/nginx.conf +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/confs/slidge-dev.ini +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/confs/slidge-example.ini +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/hot-reload.sh +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/dev/prettify_tests.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/doap.xml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docker-compose.yml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/Makefile +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/attachments.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/component.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/config/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/daemon.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/examples/ejabberd.yaml +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/examples/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/examples/prosody.cfg.lua +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/install.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/note.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/admin/privilege.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/codeberg.svg +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/conf.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/dev/contributing.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/dev/design.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/dev/howto.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/dev/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/dev/tutorial.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/glossary.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/commands.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/contacts.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/foxyproxy.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/gajim.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/index.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/low_profile.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/movim1.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/movim2.png +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/note.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/docs/source/user/register.rst +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/setup.cfg +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/__main__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/adhoc.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/admin.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/base.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/categories.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/chat_command.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/register.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/command/user.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/contact/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/contact/contact.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/contact/roster.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/config.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/caps.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/disco.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/message/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/message/chat_state.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/message/marker.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/message/message.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/admin.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/mam.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/misc.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/owner.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/muc/ping.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/presence.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/registration.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/search.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/session_dispatcher.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/util.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/dispatcher/vcard.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/avatar.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/base.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/db.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/disco.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/lock.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/message.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/message_maker.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/message_text.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/presence.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/mixins/recipient.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/core/session.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/env.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/script.py.mako +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/04cf35e3cf85_add_participant_nickname_no_illegal.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/avatar.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/meta.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/db/models.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/group/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/group/archive.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/group/bookmarks.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/migration.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/py.typed +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/delivery_receipt.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/link_preview/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/link_preview/link_preview.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/link_preview/stanza.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/roster.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0077/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0077/register.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0077/stanza.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0100/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0100/gateway.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0100/stanza.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0153/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0292/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/slixfix/xep_0292/vcard4.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/archive_msg.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/jid_escaping.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/test.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/types.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge/util/util.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/dependency_links.txt +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/entry_points.txt +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/slidge.egg-info/top_level.txt +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/__init__.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/contact.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/gateway.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/group.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/legacy_client.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/session.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/superduper/util.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/conftest.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_adhoc/test_access.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_adhoc/test_confirmation.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_adhoc/test_form.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_adhoc/test_reported.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_attachment.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_avatar.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_backfill.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_chat_commands.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_config.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_db/test_store.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_db/test_user.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_feature_restriction.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_mam_archivable.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_mds.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_name_in_constructor.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_resourceprep.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_session.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_session_2.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_set_name_before_fill.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_shakespeare.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_stanza_link_preview.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_util.py +0 -0
- {slidge-0.2.9 → slidge-0.2.11}/tests/test_vcard.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: slidge
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.11
|
4
4
|
Summary: XMPP bridging framework
|
5
5
|
Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
@@ -23,21 +23,16 @@ Requires-Dist: defusedxml>=0.7.1
|
|
23
23
|
Requires-Dist: pillow<12,>=11.0.0
|
24
24
|
Requires-Dist: python-magic<0.5,>=0.4.27
|
25
25
|
Requires-Dist: qrcode<9,>=8.0
|
26
|
-
Requires-Dist: slixmpp<2,>=1.
|
26
|
+
Requires-Dist: slixmpp<2,>=1.10.0
|
27
27
|
Requires-Dist: sqlalchemy<3,>=2
|
28
28
|
Requires-Dist: thumbhash>=0.1.2
|
29
29
|
Dynamic: license-file
|
30
30
|
|
31
31
|

|
32
32
|
|
33
|
-
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
34
|
-
|
35
|
-
|
36
33
|
[](https://ci.codeberg.org/repos/14027)
|
37
|
-
[](https://slidge.im/coverage/main)
|
38
|
-
|
39
|
-
[](https://pypi.org/project/slidge/)
|
40
|
-
[](https://packages.debian.org/unstable/python3-slidge)
|
34
|
+
[](https://slidge.im/coverage/slidge/main)
|
35
|
+
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
41
36
|
|
42
37
|
Slidge is an XMPP (puppeteer) gateway library in python.
|
43
38
|
It makes
|
@@ -104,8 +99,12 @@ or the
|
|
104
99
|
[slidge-debian](https://git.sr.ht/~nicoco/slidge-debian)
|
105
100
|
bundle.
|
106
101
|
|
102
|
+
[](https://pypi.org/project/slidge/)
|
103
|
+
|
104
|
+
[](https://repology.org/project/slidge/versions)
|
105
|
+
|
107
106
|
Slidge is available on
|
108
|
-
[codeberg](https://codeberg.org/slidge
|
107
|
+
[codeberg](https://codeberg.org/slidge/slidge/releases)
|
109
108
|
and [pypi](https://pypi.org/project/slidge/).
|
110
109
|
Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
|
111
110
|
|
@@ -1,13 +1,8 @@
|
|
1
1
|

|
2
2
|
|
3
|
-
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
4
|
-
|
5
|
-
|
6
3
|
[](https://ci.codeberg.org/repos/14027)
|
7
|
-
[](https://slidge.im/coverage/main)
|
8
|
-
|
9
|
-
[](https://pypi.org/project/slidge/)
|
10
|
-
[](https://packages.debian.org/unstable/python3-slidge)
|
4
|
+
[](https://slidge.im/coverage/slidge/main)
|
5
|
+
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
11
6
|
|
12
7
|
Slidge is an XMPP (puppeteer) gateway library in python.
|
13
8
|
It makes
|
@@ -74,8 +69,12 @@ or the
|
|
74
69
|
[slidge-debian](https://git.sr.ht/~nicoco/slidge-debian)
|
75
70
|
bundle.
|
76
71
|
|
72
|
+
[](https://pypi.org/project/slidge/)
|
73
|
+
|
74
|
+
[](https://repology.org/project/slidge/versions)
|
75
|
+
|
77
76
|
Slidge is available on
|
78
|
-
[codeberg](https://codeberg.org/slidge
|
77
|
+
[codeberg](https://codeberg.org/slidge/slidge/releases)
|
79
78
|
and [pypi](https://pypi.org/project/slidge/).
|
80
79
|
Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
|
81
80
|
|
@@ -28,8 +28,7 @@ def entrypoint(module_name: str) -> None:
|
|
28
28
|
|
29
29
|
:param module_name: An importable :term:`Legacy Module`.
|
30
30
|
"""
|
31
|
-
|
32
|
-
main_func()
|
31
|
+
main_func(module_name)
|
33
32
|
|
34
33
|
|
35
34
|
def formatwarning(message, category, filename, lineno, line=""):
|
@@ -31,6 +31,7 @@ from slidge.core.pubsub import PubSubComponent
|
|
31
31
|
from slidge.core.session import BaseSession
|
32
32
|
from slidge.db import GatewayUser, SlidgeStore
|
33
33
|
from slidge.db.avatar import avatar_cache
|
34
|
+
from slidge.slixfix import PrivilegedIqError
|
34
35
|
from slidge.slixfix.delivery_receipt import DeliveryReceipt
|
35
36
|
from slidge.slixfix.roster import RosterBackend
|
36
37
|
from slidge.util import ABCSubclassableOnceAtMost
|
@@ -474,11 +475,12 @@ class BaseGateway(
|
|
474
475
|
"create the MDS node of %s",
|
475
476
|
user_jid,
|
476
477
|
)
|
477
|
-
except
|
478
|
+
except PrivilegedIqError as exc:
|
479
|
+
nested = exc.nested_error()
|
478
480
|
# conflict this means the node already exists, we can ignore that
|
479
|
-
if
|
481
|
+
if nested is not None and nested.condition != "conflict":
|
480
482
|
log.exception(
|
481
|
-
"Could not create the MDS node of %s", user_jid, exc_info=
|
483
|
+
"Could not create the MDS node of %s", user_jid, exc_info=exc
|
482
484
|
)
|
483
485
|
except Exception as e:
|
484
486
|
log.exception(
|
@@ -46,7 +46,7 @@ class AttachmentMixin(TextMessageMixin):
|
|
46
46
|
file_path: Path,
|
47
47
|
file_name: Optional[str] = None,
|
48
48
|
content_type: Optional[str] = None,
|
49
|
-
):
|
49
|
+
) -> str | None:
|
50
50
|
if file_name and file_path.name != file_name:
|
51
51
|
d = Path(tempfile.mkdtemp())
|
52
52
|
temp = d / file_name
|
@@ -215,7 +215,7 @@ class AttachmentMixin(TextMessageMixin):
|
|
215
215
|
else:
|
216
216
|
local_path = file_path
|
217
217
|
new_url = await self.__upload(file_path, file_name, content_type)
|
218
|
-
if legacy_file_id:
|
218
|
+
if legacy_file_id and new_url is not None:
|
219
219
|
self.__store.set_url(self.session.user_pk, str(legacy_file_id), new_url)
|
220
220
|
|
221
221
|
return is_temp, local_path, new_url
|
@@ -11,7 +11,7 @@ from slixmpp import (
|
|
11
11
|
StanzaPath,
|
12
12
|
register_stanza_plugin,
|
13
13
|
)
|
14
|
-
from slixmpp.exceptions import XMPPError
|
14
|
+
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
15
15
|
from slixmpp.plugins.base import BasePlugin, register_plugin
|
16
16
|
from slixmpp.plugins.xep_0060.stanza import Event, EventItem, EventItems, Item
|
17
17
|
from slixmpp.plugins.xep_0084 import Data as AvatarData
|
@@ -134,7 +134,11 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
|
|
134
134
|
info = None
|
135
135
|
if info is None:
|
136
136
|
async with self.lock(from_):
|
137
|
-
|
137
|
+
try:
|
138
|
+
iq = await self.xmpp.plugin["xep_0030"].get_info(from_)
|
139
|
+
except (IqError, IqTimeout):
|
140
|
+
log.debug("Could get disco#info of %s, ignoring", from_)
|
141
|
+
return []
|
138
142
|
info = iq["disco_info"]
|
139
143
|
return info["features"]
|
140
144
|
|
@@ -1076,6 +1076,7 @@ class ParticipantStore(EngineMixin):
|
|
1076
1076
|
update(Participant)
|
1077
1077
|
.where(Participant.id == participant.pk)
|
1078
1078
|
.values(
|
1079
|
+
nickname=participant.nickname,
|
1079
1080
|
resource=participant.jid.resource,
|
1080
1081
|
nickname_no_illegal=participant._nickname_no_illegal,
|
1081
1082
|
affiliation=participant.affiliation,
|
@@ -648,7 +648,7 @@ class LegacyMUC(
|
|
648
648
|
since = self.xmpp.plugin["xep_0082"].parse(history_params["since"])
|
649
649
|
except ValueError:
|
650
650
|
since = None
|
651
|
-
if seconds:
|
651
|
+
if seconds is not None:
|
652
652
|
since = datetime.now() - timedelta(seconds=seconds)
|
653
653
|
if equals_zero(maxchars) or equals_zero(maxstanzas):
|
654
654
|
log.debug("Joining client does not want any old-school MUC history-on-join")
|
@@ -60,7 +60,7 @@ class SigTermInterrupt(Exception):
|
|
60
60
|
pass
|
61
61
|
|
62
62
|
|
63
|
-
def get_configurator():
|
63
|
+
def get_configurator(from_entrypoint: bool = False):
|
64
64
|
p = configargparse.ArgumentParser(
|
65
65
|
default_config_files=os.getenv(
|
66
66
|
"SLIDGE_CONF_DIR", "/etc/slidge/conf.d/*.conf"
|
@@ -98,7 +98,9 @@ def get_configurator():
|
|
98
98
|
action="version",
|
99
99
|
version=f"%(prog)s {slidge.__version__}",
|
100
100
|
)
|
101
|
-
configurator = MainConfig(
|
101
|
+
configurator = MainConfig(
|
102
|
+
config, p, skip_options=("legacy_module",) if from_entrypoint else ()
|
103
|
+
)
|
102
104
|
return configurator
|
103
105
|
|
104
106
|
|
@@ -106,8 +108,8 @@ def get_parser():
|
|
106
108
|
return get_configurator().parser
|
107
109
|
|
108
110
|
|
109
|
-
def configure():
|
110
|
-
configurator = get_configurator()
|
111
|
+
def configure(from_entrypoint: bool):
|
112
|
+
configurator = get_configurator(from_entrypoint)
|
111
113
|
args, unknown_argv = configurator.set_conf()
|
112
114
|
|
113
115
|
if not (h := config.HOME_DIR).exists():
|
@@ -124,12 +126,16 @@ def handle_sigterm(_signum, _frame):
|
|
124
126
|
raise SigTermInterrupt
|
125
127
|
|
126
128
|
|
127
|
-
def main():
|
129
|
+
def main(module_name: str | None = None) -> None:
|
130
|
+
from_entrypoint = module_name is not None
|
128
131
|
signal.signal(signal.SIGTERM, handle_sigterm)
|
129
132
|
|
130
|
-
unknown_argv = configure()
|
133
|
+
unknown_argv = configure(from_entrypoint)
|
131
134
|
logging.info("Starting slidge version %s", slidge.__version__)
|
132
135
|
|
136
|
+
if module_name is not None:
|
137
|
+
config.LEGACY_MODULE = module_name
|
138
|
+
|
133
139
|
legacy_module = importlib.import_module(config.LEGACY_MODULE)
|
134
140
|
logging.debug("Legacy module: %s", dir(legacy_module))
|
135
141
|
logging.info(
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# This module contains patches for slixmpp; some have pending requests upstream
|
2
|
+
# and should be removed on the next slixmpp release.
|
3
|
+
|
4
|
+
# ruff: noqa: F401
|
5
|
+
|
6
|
+
import uuid
|
7
|
+
|
8
|
+
import slixmpp.plugins
|
9
|
+
import slixmpp.stanza.roster
|
10
|
+
from slixmpp import Message
|
11
|
+
from slixmpp.exceptions import IqError
|
12
|
+
from slixmpp.plugins.xep_0050 import XEP_0050, Command
|
13
|
+
from slixmpp.plugins.xep_0356.permissions import IqPermission
|
14
|
+
from slixmpp.plugins.xep_0356.privilege import XEP_0356
|
15
|
+
from slixmpp.plugins.xep_0469.stanza import NS as PINNED_NS
|
16
|
+
from slixmpp.plugins.xep_0469.stanza import Pinned
|
17
|
+
from slixmpp.xmlstream import StanzaBase
|
18
|
+
|
19
|
+
from . import (
|
20
|
+
link_preview,
|
21
|
+
xep_0077,
|
22
|
+
xep_0100,
|
23
|
+
xep_0153,
|
24
|
+
xep_0292,
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
def set_pinned(self, val: bool):
|
29
|
+
extensions = self.parent()
|
30
|
+
if val:
|
31
|
+
extensions.enable("pinned")
|
32
|
+
else:
|
33
|
+
extensions._del_sub(f"{{{PINNED_NS}}}pinned")
|
34
|
+
|
35
|
+
|
36
|
+
Pinned.set_pinned = set_pinned
|
37
|
+
|
38
|
+
|
39
|
+
def session_bind(self, jid):
|
40
|
+
self.xmpp["xep_0030"].add_feature(Command.namespace)
|
41
|
+
# awful hack to for the disco items: we need to comment this line
|
42
|
+
# related issue: https://todo.sr.ht/~nicoco/slidge/131
|
43
|
+
# self.xmpp['xep_0030'].set_items(node=Command.namespace, items=tuple())
|
44
|
+
|
45
|
+
|
46
|
+
XEP_0050.session_bind = session_bind # type:ignore
|
47
|
+
|
48
|
+
|
49
|
+
def reply(self, body=None, clear=True):
|
50
|
+
"""
|
51
|
+
Overrides slixmpp's Message.reply(), since it strips to sender's resource
|
52
|
+
for mtype=groupchat, and we do not want that, because when we raise an XMPPError,
|
53
|
+
we actually want to preserve the resource.
|
54
|
+
(this is called in RootStanza.exception() to handle XMPPErrors)
|
55
|
+
"""
|
56
|
+
new_message = StanzaBase.reply(self, clear)
|
57
|
+
new_message["thread"] = self["thread"]
|
58
|
+
new_message["parent_thread"] = self["parent_thread"]
|
59
|
+
|
60
|
+
del new_message["id"]
|
61
|
+
if self.stream is not None and self.stream.use_message_ids:
|
62
|
+
new_message["id"] = self.stream.new_id()
|
63
|
+
|
64
|
+
if body is not None:
|
65
|
+
new_message["body"] = body
|
66
|
+
return new_message
|
67
|
+
|
68
|
+
|
69
|
+
Message.reply = reply # type: ignore
|
70
|
+
|
71
|
+
# TODO: remove me when https://codeberg.org/poezio/slixmpp/pulls/3622 is merged
|
72
|
+
|
73
|
+
|
74
|
+
class PrivilegedIqError(IqError):
|
75
|
+
"""
|
76
|
+
Exception raised when sending a privileged IQ stanza fails.
|
77
|
+
"""
|
78
|
+
|
79
|
+
def nested_error(self) -> IqError | None:
|
80
|
+
"""
|
81
|
+
Return the IQError generated from the inner IQ stanza, if present.
|
82
|
+
"""
|
83
|
+
if "privilege" in self.iq:
|
84
|
+
if "forwarded" in self.iq["privilege"]:
|
85
|
+
if "iq" in self.iq["privilege"]["forwarded"]:
|
86
|
+
return IqError(self.iq["privilege"]["forwarded"]["iq"])
|
87
|
+
return None
|
88
|
+
|
89
|
+
|
90
|
+
async def send_privileged_iq(self, encapsulated_iq, iq_id=None):
|
91
|
+
"""
|
92
|
+
Send an IQ on behalf of a user
|
93
|
+
|
94
|
+
Caution: the IQ *must* have the jabber:client namespace
|
95
|
+
|
96
|
+
Raises :class:`PrivilegedIqError` on failure.
|
97
|
+
"""
|
98
|
+
iq_id = iq_id or str(uuid.uuid4())
|
99
|
+
encapsulated_iq["id"] = iq_id
|
100
|
+
server = encapsulated_iq.get_to().domain
|
101
|
+
perms = self.granted_privileges.get(server)
|
102
|
+
if not perms:
|
103
|
+
raise PermissionError(f"{server} has not granted us any privilege")
|
104
|
+
itype = encapsulated_iq["type"]
|
105
|
+
for ns in encapsulated_iq.plugins.values():
|
106
|
+
type_ = perms.iq[ns.namespace]
|
107
|
+
if type_ == IqPermission.NONE:
|
108
|
+
raise PermissionError(
|
109
|
+
f"{server} has not granted any IQ privilege for namespace {ns.namespace}"
|
110
|
+
)
|
111
|
+
elif type_ == IqPermission.BOTH:
|
112
|
+
pass
|
113
|
+
elif type_ != itype:
|
114
|
+
raise PermissionError(
|
115
|
+
f"{server} has not granted IQ {itype} privilege for namespace {ns.namespace}"
|
116
|
+
)
|
117
|
+
iq = self.xmpp.make_iq(
|
118
|
+
itype=itype,
|
119
|
+
ifrom=self.xmpp.boundjid.bare,
|
120
|
+
ito=encapsulated_iq.get_from(),
|
121
|
+
id=iq_id,
|
122
|
+
)
|
123
|
+
iq["privileged_iq"].append(encapsulated_iq)
|
124
|
+
|
125
|
+
try:
|
126
|
+
resp = await iq.send()
|
127
|
+
except IqError as exc:
|
128
|
+
raise PrivilegedIqError(exc.iq)
|
129
|
+
|
130
|
+
return resp["privilege"]["forwarded"]["iq"]
|
131
|
+
|
132
|
+
|
133
|
+
XEP_0356.send_privileged_iq = send_privileged_iq
|
134
|
+
|
135
|
+
|
136
|
+
slixmpp.plugins.PLUGINS.extend(
|
137
|
+
[
|
138
|
+
"link_preview",
|
139
|
+
"xep_0292_provider",
|
140
|
+
]
|
141
|
+
)
|
@@ -95,20 +95,27 @@ class ConfigModule:
|
|
95
95
|
ENV_VAR_PREFIX = "SLIDGE_"
|
96
96
|
|
97
97
|
def __init__(
|
98
|
-
self,
|
98
|
+
self,
|
99
|
+
config_obj,
|
100
|
+
parser: Optional[configargparse.ArgumentParser] = None,
|
101
|
+
skip_options: tuple[str, ...] = (),
|
99
102
|
):
|
100
103
|
self.config_obj = config_obj
|
101
104
|
if parser is None:
|
102
105
|
parser = configargparse.ArgumentParser()
|
103
106
|
self.parser = parser
|
104
107
|
|
105
|
-
self.
|
108
|
+
self.skip_options = skip_options
|
109
|
+
self.add_options_to_parser(skip_options)
|
106
110
|
|
107
111
|
def _list_options(self):
|
108
112
|
return {
|
109
113
|
o
|
110
114
|
for o in (set(dir(self.config_obj)) | set(get_type_hints(self.config_obj)))
|
111
|
-
if o.upper() == o
|
115
|
+
if o.upper() == o
|
116
|
+
and not o.startswith("_")
|
117
|
+
and "__" not in o
|
118
|
+
and o.lower() not in self.skip_options
|
112
119
|
}
|
113
120
|
|
114
121
|
def set_conf(self, argv: Optional[list[str]] = None):
|
@@ -179,9 +186,12 @@ class ConfigModule:
|
|
179
186
|
res.append(Option(self, opt))
|
180
187
|
return res
|
181
188
|
|
182
|
-
def add_options_to_parser(self):
|
189
|
+
def add_options_to_parser(self, skip_options: tuple[str, ...]):
|
190
|
+
skip_options = tuple(o.lower() for o in skip_options)
|
183
191
|
p = self.parser
|
184
192
|
for o in sorted(self.options, key=lambda x: (not x.required, x.name)):
|
193
|
+
if o.name.lower() in skip_options:
|
194
|
+
continue
|
185
195
|
p.add_argument(*o.names, **o.kwargs)
|
186
196
|
|
187
197
|
def update_dynamic_defaults(self, args):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: slidge
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.11
|
4
4
|
Summary: XMPP bridging framework
|
5
5
|
Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
@@ -23,21 +23,16 @@ Requires-Dist: defusedxml>=0.7.1
|
|
23
23
|
Requires-Dist: pillow<12,>=11.0.0
|
24
24
|
Requires-Dist: python-magic<0.5,>=0.4.27
|
25
25
|
Requires-Dist: qrcode<9,>=8.0
|
26
|
-
Requires-Dist: slixmpp<2,>=1.
|
26
|
+
Requires-Dist: slixmpp<2,>=1.10.0
|
27
27
|
Requires-Dist: sqlalchemy<3,>=2
|
28
28
|
Requires-Dist: thumbhash>=0.1.2
|
29
29
|
Dynamic: license-file
|
30
30
|
|
31
31
|

|
32
32
|
|
33
|
-
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
34
|
-
|
35
|
-
|
36
33
|
[](https://ci.codeberg.org/repos/14027)
|
37
|
-
[](https://slidge.im/coverage/main)
|
38
|
-
|
39
|
-
[](https://pypi.org/project/slidge/)
|
40
|
-
[](https://packages.debian.org/unstable/python3-slidge)
|
34
|
+
[](https://slidge.im/coverage/slidge/main)
|
35
|
+
[](https://conference.nicoco.fr:5281/muc_log/slidge/)
|
41
36
|
|
42
37
|
Slidge is an XMPP (puppeteer) gateway library in python.
|
43
38
|
It makes
|
@@ -104,8 +99,12 @@ or the
|
|
104
99
|
[slidge-debian](https://git.sr.ht/~nicoco/slidge-debian)
|
105
100
|
bundle.
|
106
101
|
|
102
|
+
[](https://pypi.org/project/slidge/)
|
103
|
+
|
104
|
+
[](https://repology.org/project/slidge/versions)
|
105
|
+
|
107
106
|
Slidge is available on
|
108
|
-
[codeberg](https://codeberg.org/slidge
|
107
|
+
[codeberg](https://codeberg.org/slidge/slidge/releases)
|
109
108
|
and [pypi](https://pypi.org/project/slidge/).
|
110
109
|
Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
|
111
110
|
|
@@ -3246,6 +3246,9 @@ class TestMuc(Base):
|
|
3246
3246
|
muc = self.run_coro(muc.session.bookmarks.by_legacy_id(muc.legacy_id))
|
3247
3247
|
participants_after = self.run_coro(self.__participants_as_list(muc))
|
3248
3248
|
assert len(participants_after) == len(participants_before)
|
3249
|
+
nicks = [p.nickname for p in participants_after]
|
3250
|
+
assert old_nick not in nicks
|
3251
|
+
assert "new-nick" in nicks
|
3249
3252
|
assert self.next_sent() is None
|
3250
3253
|
|
3251
3254
|
def test_rename_participant_from_participant(self):
|