slidge 0.2.7.post1__tar.gz → 0.2.8__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.7.post1 → slidge-0.2.8}/.woodpecker/test.yaml +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/Dockerfile +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/PKG-INFO +2 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/daemon.rst +6 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/install.rst +2 -8
- {slidge-0.2.7.post1 → slidge-0.2.8}/pyproject.toml +26 -18
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/__version__.py +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/contact/contact.py +2 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/contact/roster.py +2 -3
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/session_dispatcher.py +6 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/gateway.py +12 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/message_maker.py +3 -3
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/store.py +3 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/group/archive.py +11 -3
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/group/bookmarks.py +4 -5
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/group/participant.py +33 -35
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/group/room.py +10 -12
- slidge-0.2.8/slidge/slixfix/__init__.py +92 -0
- slidge-0.2.8/slidge/util/jid_escaping.py +52 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/PKG-INFO +2 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/SOURCES.txt +2 -3
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/requires.txt +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_adhoc/test_access.py +2 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_adhoc/test_confirmation.py +2 -2
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_adhoc/test_form.py +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_adhoc/test_reported.py +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_chat_commands.py +1 -1
- slidge-0.2.8/tests/test_mam_archivable.py +49 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_mds.py +1 -1
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_muc.py +13 -8
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_session.py +6 -5
- {slidge-0.2.7.post1 → slidge-0.2.8}/uv.lock +18 -4
- slidge-0.2.7.post1/slidge/slixfix/__init__.py +0 -152
- slidge-0.2.7.post1/slidge/slixfix/xep_0492/__init__.py +0 -8
- slidge-0.2.7.post1/slidge/slixfix/xep_0492/notify.py +0 -16
- slidge-0.2.7.post1/slidge/slixfix/xep_0492/stanza.py +0 -107
- {slidge-0.2.7.post1 → slidge-0.2.8}/.gitignore +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.pre-commit-config.yaml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.woodpecker/container-cache.yml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.woodpecker/container-ci.yaml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.woodpecker/container.yml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.woodpecker/docs.yaml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/.woodpecker/package.yaml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/LICENSE +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/README.md +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/commitlint.config.js +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/5x5.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/slidge-color-small.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/slidge-color.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/slidge-mono-black.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/slidge-mono-white.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/assets/slidge.svg +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/confs/movim.env +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/confs/nginx.conf +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/confs/slidge-example.ini +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/dev/prettify_tests.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/doap.xml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docker-compose.yml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/Makefile +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/attachments.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/component.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/config/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/examples/ejabberd.yaml +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/examples/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/examples/prosody.cfg.lua +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/note.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/admin/privilege.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/codeberg.svg +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/conf.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/dev/contributing.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/dev/design.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/dev/howto.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/dev/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/dev/tutorial.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/glossary.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/commands.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/contacts.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/foxyproxy.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/gajim.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/index.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/low_profile.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/movim1.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/movim2.png +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/note.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/docs/source/user/register.rst +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/setup.cfg +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/__main__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/adhoc.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/admin.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/base.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/categories.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/chat_command.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/register.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/command/user.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/contact/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/config.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/caps.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/disco.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/message/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/message/chat_state.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/message/marker.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/message/message.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/admin.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/mam.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/misc.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/owner.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/muc/ping.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/presence.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/registration.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/search.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/util.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/dispatcher/vcard.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/attachment.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/avatar.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/base.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/db.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/disco.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/lock.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/message.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/message_text.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/presence.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/mixins/recipient.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/pubsub.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/core/session.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/env.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/script.py.mako +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/04cf35e3cf85_add_participant_nickname_no_illegal.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/avatar.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/meta.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/db/models.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/group/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/main.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/migration.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/py.typed +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/delivery_receipt.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/link_preview/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/link_preview/link_preview.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/link_preview/stanza.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/roster.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0077/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0077/register.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0077/stanza.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0100/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0100/gateway.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0100/stanza.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0153/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0292/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/slixfix/xep_0292/vcard4.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/archive_msg.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/conf.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/test.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/types.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge/util/util.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/dependency_links.txt +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/entry_points.txt +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/slidge.egg-info/top_level.txt +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/__init__.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/contact.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/gateway.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/group.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/legacy_client.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/session.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/superduper/util.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/conftest.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_attachment.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_avatar.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_backfill.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_config.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_db/test_store.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_db/test_user.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_feature_restriction.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_name_in_constructor.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_resourceprep.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_session_2.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_set_name_before_fill.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_shakespeare.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_stanza_link_preview.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_util.py +0 -0
- {slidge-0.2.7.post1 → slidge-0.2.8}/tests/test_vcard.py +0 -0
@@ -20,7 +20,7 @@ RUN apt-get update -y && apt-get install -y --no-install-recommends \
|
|
20
20
|
python3-dev \
|
21
21
|
rustc
|
22
22
|
|
23
|
-
RUN uv venv /venv
|
23
|
+
RUN uv venv /venv --relocatable
|
24
24
|
WORKDIR /build
|
25
25
|
# Only copy files used to define dependencies, so this step can be in cache
|
26
26
|
# as long as we don't touch the deps.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: slidge
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.8
|
4
4
|
Summary: XMPP bridging framework
|
5
5
|
Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
@@ -683,7 +683,7 @@ Requires-Dist: defusedxml>=0.7.1
|
|
683
683
|
Requires-Dist: pillow<12,>=11.0.0
|
684
684
|
Requires-Dist: python-magic<0.5,>=0.4.27
|
685
685
|
Requires-Dist: qrcode<9,>=8.0
|
686
|
-
Requires-Dist: slixmpp<1.9.0
|
686
|
+
Requires-Dist: slixmpp<2,>=1.9.0
|
687
687
|
Requires-Dist: sqlalchemy<3,>=2
|
688
688
|
Requires-Dist: thumbhash>=0.1.2
|
689
689
|
|
@@ -15,8 +15,12 @@ contributions are welcome).
|
|
15
15
|
|
16
16
|
In this page we assume that you have fulfilled the basic :ref:`XMPP server config`.
|
17
17
|
|
18
|
-
Debian packages (
|
19
|
-
|
18
|
+
Debian packages (unofficial)
|
19
|
+
============================
|
20
|
+
|
21
|
+
These instructions are for the slidge bundle unofficial package hosted on
|
22
|
+
`codeberg <https://codeberg.org/slidge/debian>`_. They do not apply to the official
|
23
|
+
debian slidge package, which is incompatible with this bundle.
|
20
24
|
|
21
25
|
Edit and remove the ``.example`` extension for ``/etc/slidge/conf.d/common.conf``
|
22
26
|
and ``/etc/slidge/superduper.conf.example``.
|
@@ -13,14 +13,8 @@ debian
|
|
13
13
|
------
|
14
14
|
|
15
15
|
A debian package containing slidge and a bunch of legacy modules is available at
|
16
|
-
`<https://
|
17
|
-
|
18
|
-
Debian packages for *bookworm* (amd64 and arm64)
|
19
|
-
are built on each push to master as artifacts of
|
20
|
-
this `build job <https://builds.sr.ht/~nicoco/slidge/commits/master/debian.yml?>`_.
|
21
|
-
|
22
|
-
A repo is maintained by IGImonster. Refer to the README of
|
23
|
-
`<https://git.sr.ht/~nicoco/slidge-debian>`_ for setup instructions.
|
16
|
+
`<https://codeberg.org/slidge/debian>`_. See the README there for details and
|
17
|
+
instructions.
|
24
18
|
|
25
19
|
See :ref:`Debian packages` for information about how to launch slidge as a daemon via systemd.
|
26
20
|
|
@@ -10,7 +10,7 @@ dependencies = [
|
|
10
10
|
"pillow>=11.0.0,<12",
|
11
11
|
"python-magic>=0.4.27,<0.5",
|
12
12
|
"qrcode>=8.0,<9",
|
13
|
-
"slixmpp>=1.
|
13
|
+
"slixmpp>=1.9.0,<2",
|
14
14
|
"sqlalchemy>=2,<3",
|
15
15
|
"thumbhash>=0.1.2",
|
16
16
|
]
|
@@ -23,7 +23,7 @@ classifiers = [
|
|
23
23
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
24
24
|
]
|
25
25
|
keywords = ["xmpp", "gateway", "bridge", "instant messaging"]
|
26
|
-
version = "v0.2.
|
26
|
+
version = "v0.2.8"
|
27
27
|
readme = "README.md"
|
28
28
|
|
29
29
|
[build-system]
|
@@ -128,14 +128,20 @@ header = """
|
|
128
128
|
# Changes
|
129
129
|
"""
|
130
130
|
body = """
|
131
|
-
{% for group,
|
131
|
+
{% for group, all_commits in commits | group_by(attribute="group") %}
|
132
|
+
{%- if group == "cfix" %}{% continue %}{%- endif %}
|
132
133
|
## {{ group | striptags | trim | upper_first }}
|
133
|
-
{% for commit in
|
134
|
+
{% for commit in all_commits %}
|
134
135
|
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
135
136
|
{% if commit.breaking %}[**breaking**] {% endif %}\
|
136
|
-
{{ commit.message | split(pat="\n") | first | upper_first | trim }}\
|
137
|
-
{
|
138
|
-
|
137
|
+
{{ commit.message | split(pat="\n") | first | upper_first | trim }} \
|
138
|
+
([`{{ commit.id | truncate(length=7, end="") }}`](./commit/{{ commit.id -}})\
|
139
|
+
{% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
|
140
|
+
{%- for cfix_commit in commits | filter(attribute="group", value="cfix") -%}
|
141
|
+
{%- if cfix_commit.scope and commit.id is starting_with(cfix_commit.scope) -%}
|
142
|
+
, [`{{ cfix_commit.id | truncate(length=7, end="") }}`](./commit/{{ cfix_commit.id }}){% if cfix_commit.remote.username %} by @{{ cfix_commit.remote.username }}{%- endif -%}
|
143
|
+
{%- endif -%}
|
144
|
+
{%- endfor -%})\
|
139
145
|
{% endfor %}
|
140
146
|
{% endfor %}\n
|
141
147
|
"""
|
@@ -148,21 +154,23 @@ conventional_commits = true
|
|
148
154
|
filter_unconventional = false
|
149
155
|
commit_parsers = [
|
150
156
|
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
151
|
-
{ message = "^imprv", group = "<!--
|
152
|
-
{ message = "^fix", group = "<!--
|
153
|
-
{ message = "^compat", group = "<!--
|
154
|
-
{ message = "^refactor", group = "<!--
|
155
|
-
{ message = "^doc", group = "<!--
|
156
|
-
{ message = "^perf", group = "<!--
|
157
|
-
{ message = "^style", group = "<!--
|
158
|
-
{ message = "^test", group = "<!--
|
157
|
+
{ message = "^imprv", group = "<!-- 01 -->✨ Improvements" },
|
158
|
+
{ message = "^fix", group = "<!-- 02 -->🐛 Bug Fixes" },
|
159
|
+
{ message = "^compat", group = "<!-- 03 -->💑 Compatibility" },
|
160
|
+
{ message = "^refactor", group = "<!-- 04 -->🚜 Refactor" },
|
161
|
+
{ message = "^doc", group = "<!-- 05 -->📚 Documentation" },
|
162
|
+
{ message = "^perf", group = "<!-- 06 -->⚡ Performance" },
|
163
|
+
{ message = "^style", group = "<!-- 07 -->🎨 Styling" },
|
164
|
+
{ message = "^test", group = "<!-- 08 -->🧪 Testing" },
|
159
165
|
{ message = "^chore\\(release\\): prepare for", skip = true },
|
160
166
|
{ message = "^chore\\(deps.*\\)", skip = true },
|
161
167
|
{ message = "^chore\\(pr\\)", skip = true },
|
162
168
|
{ message = "^chore\\(pull\\)", skip = true },
|
163
|
-
{ message = "^
|
164
|
-
{ message = "^chore
|
169
|
+
{ message = "^build\\(lockfile\\)", skip = true },
|
170
|
+
{ message = "^chore\\(lockfile\\)", skip = true },
|
171
|
+
{ message = "^chore|^ci", group = "<!-- 09 -->⚙️ Miscellaneous Tasks" },
|
165
172
|
{ body = ".*security", group = "<!-- 10 -->🛡️ Security" },
|
166
173
|
{ message = "^revert", group = "<!-- 11 -->◀️ Revert" },
|
167
|
-
{ message = "
|
174
|
+
{ message = "^cfix", group = "cfix" },
|
175
|
+
{ message = ".*", group = "<!-- 13 -->💼 Other" },
|
168
176
|
]
|
@@ -218,7 +218,7 @@ class LegacyContact(
|
|
218
218
|
self.log.name = f"{self.user_jid.bare}:contact:{self}"
|
219
219
|
|
220
220
|
def __repr__(self):
|
221
|
-
return f"<Contact #{self.contact_pk} '{self.name}' ({self.legacy_id} - {self.jid.
|
221
|
+
return f"<Contact #{self.contact_pk} '{self.name}' ({self.legacy_id} - {self.jid.user})'>"
|
222
222
|
|
223
223
|
def __ensure_pk(self):
|
224
224
|
if self.contact_pk is not None:
|
@@ -617,7 +617,7 @@ class LegacyContact(
|
|
617
617
|
contact = cls(
|
618
618
|
session,
|
619
619
|
cls.xmpp.LEGACY_CONTACT_ID_TYPE(stored.legacy_id),
|
620
|
-
stored.jid.
|
620
|
+
stored.jid.user, # type: ignore
|
621
621
|
*args, # type: ignore
|
622
622
|
**kwargs, # type: ignore
|
623
623
|
)
|
@@ -5,12 +5,12 @@ from typing import TYPE_CHECKING, AsyncIterator, Generic, Iterator, Optional, Ty
|
|
5
5
|
|
6
6
|
from slixmpp import JID
|
7
7
|
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
8
|
-
from slixmpp.jid import JID_UNESCAPE_TRANSFORMATIONS, _unescape_node
|
9
8
|
|
10
9
|
from ..core.mixins.lock import NamedLockMixin
|
11
10
|
from ..db.models import Contact
|
12
11
|
from ..db.store import ContactStore
|
13
12
|
from ..util import SubclassableOnce
|
13
|
+
from ..util.jid_escaping import ESCAPE_TABLE, unescape_node
|
14
14
|
from ..util.types import LegacyContactType, LegacyUserIdType
|
15
15
|
from .contact import LegacyContact
|
16
16
|
|
@@ -198,7 +198,7 @@ class LegacyRoster(
|
|
198
198
|
:param jid_username: User part of a JID, ie "user" in "user@example.com"
|
199
199
|
:return: An identifier for the user on the legacy network.
|
200
200
|
"""
|
201
|
-
return
|
201
|
+
return unescape_node(jid_username)
|
202
202
|
|
203
203
|
async def _fill(self):
|
204
204
|
try:
|
@@ -259,5 +259,4 @@ class LegacyRoster(
|
|
259
259
|
yield
|
260
260
|
|
261
261
|
|
262
|
-
ESCAPE_TABLE = "".maketrans({v: k for k, v in JID_UNESCAPE_TRANSFORMATIONS.items()})
|
263
262
|
log = logging.getLogger(__name__)
|
@@ -52,7 +52,6 @@ class SessionDispatcher(
|
|
52
52
|
if session.user.avatar_hash == hash_:
|
53
53
|
session.log.debug("We already know this avatar hash")
|
54
54
|
return
|
55
|
-
self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
|
56
55
|
|
57
56
|
if hash_:
|
58
57
|
try:
|
@@ -67,6 +66,7 @@ class SessionDispatcher(
|
|
67
66
|
height = info["height"]
|
68
67
|
width = info["width"]
|
69
68
|
else:
|
69
|
+
self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
|
70
70
|
bytes_ = type_ = height = width = hash_ = None
|
71
71
|
try:
|
72
72
|
await session.on_avatar(bytes_, hash_, type_, width, height)
|
@@ -79,6 +79,11 @@ class SessionDispatcher(
|
|
79
79
|
session.send_gateway_message(
|
80
80
|
f"Something went wrong trying to set your avatar: {e!r}"
|
81
81
|
)
|
82
|
+
else:
|
83
|
+
self.xmpp.store.users.set_avatar_hash(session.user_pk, hash_)
|
84
|
+
for room in session.bookmarks:
|
85
|
+
participant = await room.get_user_participant()
|
86
|
+
participant.send_last_presence(force=True, no_cache_online=True)
|
82
87
|
|
83
88
|
|
84
89
|
log = logging.getLogger(__name__)
|
@@ -559,8 +559,18 @@ class BaseGateway(
|
|
559
559
|
self.xmpp.plugin["xep_0084"].stanza.MetaData.namespace,
|
560
560
|
ifrom=self.boundjid.bare,
|
561
561
|
)
|
562
|
-
except
|
563
|
-
self.
|
562
|
+
except IqTimeout:
|
563
|
+
self.log.warning("Iq timeout trying to fetch user avatar")
|
564
|
+
return
|
565
|
+
except IqError as e:
|
566
|
+
self.log.debug("Iq error when trying to fetch user avatar: %s", e)
|
567
|
+
if e.condition == "item-not-found":
|
568
|
+
try:
|
569
|
+
await session.on_avatar(None, None, None, None, None)
|
570
|
+
except NotImplementedError:
|
571
|
+
pass
|
572
|
+
else:
|
573
|
+
self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
|
564
574
|
return
|
565
575
|
await self.__dispatcher.on_avatar_metadata_info(
|
566
576
|
session, iq["pubsub"]["items"]["item"]["avatar_metadata"]["info"]
|
@@ -4,7 +4,7 @@ from datetime import datetime, timezone
|
|
4
4
|
from typing import TYPE_CHECKING, Iterable, Optional, cast
|
5
5
|
from uuid import uuid4
|
6
6
|
|
7
|
-
from slixmpp import Message
|
7
|
+
from slixmpp import JID, Message
|
8
8
|
from slixmpp.types import MessageTypes
|
9
9
|
|
10
10
|
from ...db.models import GatewayUser
|
@@ -120,14 +120,14 @@ class MessageMaker(BaseSender):
|
|
120
120
|
DeprecationWarning,
|
121
121
|
)
|
122
122
|
if muc:
|
123
|
-
jid =
|
123
|
+
jid = JID(muc.jid)
|
124
124
|
jid.resource = fallback_nick = muc.user_nick
|
125
125
|
msg["reply"]["to"] = jid
|
126
126
|
else:
|
127
127
|
msg["reply"]["to"] = self.session.user_jid
|
128
128
|
# TODO: here we should use preferably use the PEP nick of the user
|
129
129
|
# (but it doesn't matter much)
|
130
|
-
fallback_nick = self.session.user_jid.
|
130
|
+
fallback_nick = self.session.user_jid.user
|
131
131
|
else:
|
132
132
|
if muc:
|
133
133
|
if hasattr(entity, "muc"):
|
@@ -443,6 +443,7 @@ class ContactStore(UpdatedMixin):
|
|
443
443
|
break
|
444
444
|
for row_id in to_del:
|
445
445
|
session.execute(delete(ContactSent).where(ContactSent.id == row_id))
|
446
|
+
session.commit()
|
446
447
|
return result
|
447
448
|
|
448
449
|
def set_friend(self, contact_pk: int, is_friend: bool) -> None:
|
@@ -751,6 +752,8 @@ class MultiStore(EngineMixin):
|
|
751
752
|
).scalar()
|
752
753
|
if multi is None:
|
753
754
|
return None
|
755
|
+
if multi.legacy_ids_multi is None:
|
756
|
+
return None
|
754
757
|
return multi.legacy_ids_multi.legacy_id
|
755
758
|
|
756
759
|
|
@@ -150,19 +150,27 @@ def archivable(msg: Message):
|
|
150
150
|
:return:
|
151
151
|
"""
|
152
152
|
|
153
|
-
if msg.get_plugin("
|
153
|
+
if msg.get_plugin("no-store", check=True):
|
154
154
|
return False
|
155
155
|
|
156
|
+
if msg.get_plugin("no-permanent-store", check=True):
|
157
|
+
return False
|
158
|
+
|
159
|
+
if msg.get_plugin("store", check=True):
|
160
|
+
return True
|
161
|
+
|
156
162
|
if msg["body"]:
|
157
163
|
return True
|
158
164
|
|
159
|
-
if msg.get_plugin("
|
160
|
-
# retractions
|
165
|
+
if msg.get_plugin("retract", check=True):
|
161
166
|
return True
|
162
167
|
|
163
168
|
if msg.get_plugin("reactions", check=True):
|
164
169
|
return True
|
165
170
|
|
171
|
+
if msg.get_plugin("displayed", check=True):
|
172
|
+
return True
|
173
|
+
|
166
174
|
return False
|
167
175
|
|
168
176
|
|
@@ -4,12 +4,11 @@ from typing import TYPE_CHECKING, Generic, Iterator, Optional, Type
|
|
4
4
|
|
5
5
|
from slixmpp import JID
|
6
6
|
from slixmpp.exceptions import XMPPError
|
7
|
-
from slixmpp.jid import _unescape_node
|
8
7
|
|
9
|
-
from ..contact.roster import ESCAPE_TABLE
|
10
8
|
from ..core.mixins.lock import NamedLockMixin
|
11
9
|
from ..db.models import Room
|
12
10
|
from ..util import SubclassableOnce
|
11
|
+
from ..util.jid_escaping import ESCAPE_TABLE, unescape_node
|
13
12
|
from ..util.types import LegacyGroupIdType, LegacyMUCType
|
14
13
|
from .archive import MessageArchive
|
15
14
|
from .room import LegacyMUC
|
@@ -83,14 +82,14 @@ class LegacyBookmarks(
|
|
83
82
|
:param username:
|
84
83
|
:return:
|
85
84
|
"""
|
86
|
-
return
|
85
|
+
return unescape_node(username)
|
87
86
|
|
88
87
|
async def by_jid(self, jid: JID) -> LegacyMUCType:
|
89
88
|
if jid.resource:
|
90
89
|
jid = JID(jid.bare)
|
91
90
|
async with self.lock(("bare", jid.bare)):
|
92
|
-
assert isinstance(jid.
|
93
|
-
legacy_id = await self.jid_local_part_to_legacy_id(jid.
|
91
|
+
assert isinstance(jid.user, str)
|
92
|
+
legacy_id = await self.jid_local_part_to_legacy_id(jid.user)
|
94
93
|
if self.get_lock(("legacy_id", legacy_id)):
|
95
94
|
self.log.debug("Not instantiating %s after all", jid)
|
96
95
|
return await self.by_legacy_id(legacy_id)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import logging
|
2
2
|
import string
|
3
|
-
import stringprep
|
4
3
|
import uuid
|
5
4
|
import warnings
|
6
5
|
from copy import copy
|
@@ -10,9 +9,7 @@ from typing import TYPE_CHECKING, Optional, Self, Union
|
|
10
9
|
|
11
10
|
from slixmpp import JID, InvalidJID, Message, Presence
|
12
11
|
from slixmpp.plugins.xep_0045.stanza import MUCAdminItem
|
13
|
-
from slixmpp.stringprep import StringprepError, resourceprep
|
14
12
|
from slixmpp.types import MessageTypes, OptJid
|
15
|
-
from slixmpp.util.stringprep_profiles import StringPrepError, prohibit_output
|
16
13
|
|
17
14
|
from ..contact import LegacyContact
|
18
15
|
from ..core.mixins import (
|
@@ -175,39 +172,22 @@ class LegacyParticipant(
|
|
175
172
|
self.send_last_presence(force=True, no_cache_online=True)
|
176
173
|
|
177
174
|
def __update_jid(self, unescaped_nickname: Optional[str]):
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
175
|
+
if not unescaped_nickname:
|
176
|
+
self.jid = JID(self.muc.jid)
|
177
|
+
if self.is_system:
|
178
|
+
self._nickname_no_illegal = ""
|
179
|
+
else:
|
180
|
+
warnings.warn(
|
181
|
+
"Only the system participant is allowed to not have a nickname"
|
182
|
+
)
|
183
|
+
nickname = f"unnamed-{uuid.uuid4()}"
|
184
|
+
self.jid.resource = self._nickname_no_illegal = nickname
|
183
185
|
return
|
184
186
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
else:
|
190
|
-
warnings.warn(
|
191
|
-
"Only the system participant is allowed to not have a nickname"
|
192
|
-
)
|
193
|
-
nickname = f"unnamed-{uuid.uuid4()}"
|
194
|
-
|
195
|
-
assert isinstance(nickname, str)
|
196
|
-
|
197
|
-
try:
|
198
|
-
# workaround for https://codeberg.org/poezio/slixmpp/issues/3480
|
199
|
-
prohibit_output(nickname, [stringprep.in_table_a1])
|
200
|
-
resourceprep(nickname)
|
201
|
-
except (StringPrepError, StringprepError):
|
202
|
-
nickname = nickname.encode("punycode").decode()
|
203
|
-
|
204
|
-
# at this point there still might be control chars
|
205
|
-
try:
|
206
|
-
j.resource = nickname
|
207
|
-
except InvalidJID:
|
208
|
-
j.resource = strip_non_printable(nickname)
|
209
|
-
|
210
|
-
self.jid = j
|
187
|
+
self._nickname_no_illegal, self.jid = escape_nickname(
|
188
|
+
self.muc.jid,
|
189
|
+
unescaped_nickname,
|
190
|
+
)
|
211
191
|
|
212
192
|
def send_configuration_change(self, codes: tuple[int]):
|
213
193
|
if not self.is_system:
|
@@ -270,7 +250,7 @@ class LegacyParticipant(
|
|
270
250
|
if user_full_jid:
|
271
251
|
p["muc"]["jid"] = user_full_jid
|
272
252
|
else:
|
273
|
-
jid =
|
253
|
+
jid = JID(self.user_jid)
|
274
254
|
try:
|
275
255
|
jid.resource = next(
|
276
256
|
iter(self.muc.get_user_resources()) # type:ignore
|
@@ -539,4 +519,22 @@ class LegacyParticipant(
|
|
539
519
|
return part
|
540
520
|
|
541
521
|
|
522
|
+
def escape_nickname(muc_jid: JID, nickname: str) -> tuple[str, JID]:
|
523
|
+
nickname = nickname_no_illegal = strip_illegal_chars(nickname)
|
524
|
+
|
525
|
+
jid = JID(muc_jid)
|
526
|
+
|
527
|
+
try:
|
528
|
+
jid.resource = nickname
|
529
|
+
except InvalidJID:
|
530
|
+
nickname = nickname.encode("punycode").decode()
|
531
|
+
try:
|
532
|
+
jid.resource = nickname
|
533
|
+
except InvalidJID:
|
534
|
+
# at this point there still might be control chars
|
535
|
+
jid.resource = strip_non_printable(nickname)
|
536
|
+
|
537
|
+
return nickname_no_illegal, jid
|
538
|
+
|
539
|
+
|
542
540
|
log = logging.getLogger(__name__)
|
@@ -10,11 +10,12 @@ from uuid import uuid4
|
|
10
10
|
|
11
11
|
from slixmpp import JID, Iq, Message, Presence
|
12
12
|
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
13
|
-
from slixmpp.jid import _unescape_node
|
14
13
|
from slixmpp.plugins.xep_0004 import Form
|
15
14
|
from slixmpp.plugins.xep_0060.stanza import Item
|
16
15
|
from slixmpp.plugins.xep_0082 import parse as str_to_datetime
|
17
16
|
from slixmpp.plugins.xep_0469.stanza import NS as PINNING_NS
|
17
|
+
from slixmpp.plugins.xep_0492.stanza import NS as NOTIFY_NS
|
18
|
+
from slixmpp.plugins.xep_0492.stanza import WhenLiteral
|
18
19
|
from slixmpp.xmlstream import ET
|
19
20
|
|
20
21
|
from ..contact.contact import LegacyContact
|
@@ -27,9 +28,8 @@ from ..core.mixins.disco import ChatterDiscoMixin
|
|
27
28
|
from ..core.mixins.lock import NamedLockMixin
|
28
29
|
from ..core.mixins.recipient import ReactionRecipientMixin, ThreadRecipientMixin
|
29
30
|
from ..db.models import Room
|
30
|
-
from ..slixfix.xep_0492.stanza import NS as NOTIFY_NS
|
31
|
-
from ..slixfix.xep_0492.stanza import WhenLiteral
|
32
31
|
from ..util import ABCSubclassableOnceAtMost
|
32
|
+
from ..util.jid_escaping import unescape_node
|
33
33
|
from ..util.types import (
|
34
34
|
HoleBound,
|
35
35
|
LegacyGroupIdType,
|
@@ -42,7 +42,7 @@ from ..util.types import (
|
|
42
42
|
)
|
43
43
|
from ..util.util import deprecated, timeit, with_session
|
44
44
|
from .archive import MessageArchive
|
45
|
-
from .participant import LegacyParticipant
|
45
|
+
from .participant import LegacyParticipant, escape_nickname
|
46
46
|
|
47
47
|
if TYPE_CHECKING:
|
48
48
|
from ..core.gateway import BaseGateway
|
@@ -184,7 +184,7 @@ class LegacyMUC(
|
|
184
184
|
self.log = logging.getLogger(f"{self.user_jid}:muc:{self}")
|
185
185
|
|
186
186
|
def __repr__(self):
|
187
|
-
return f"<MUC #{self.pk} '{self.name}' ({self.legacy_id} - {self.jid.
|
187
|
+
return f"<MUC #{self.pk} '{self.name}' ({self.legacy_id} - {self.jid.user})'>"
|
188
188
|
|
189
189
|
@property
|
190
190
|
def subject_date(self) -> Optional[datetime]:
|
@@ -515,8 +515,7 @@ class LegacyMUC(
|
|
515
515
|
return r
|
516
516
|
|
517
517
|
def shutdown(self):
|
518
|
-
user_jid =
|
519
|
-
user_jid.resource = self.user_nick
|
518
|
+
_, user_jid = escape_nickname(self.jid, self.user_nick)
|
520
519
|
for user_full_jid in self.user_full_jids():
|
521
520
|
presence = self.xmpp.make_presence(
|
522
521
|
pfrom=user_jid, pto=user_full_jid, ptype="unavailable"
|
@@ -528,14 +527,13 @@ class LegacyMUC(
|
|
528
527
|
|
529
528
|
def user_full_jids(self):
|
530
529
|
for r in self._user_resources:
|
531
|
-
j =
|
530
|
+
j = JID(self.user_jid)
|
532
531
|
j.resource = r
|
533
532
|
yield j
|
534
533
|
|
535
534
|
@property
|
536
535
|
def user_muc_jid(self):
|
537
|
-
user_muc_jid =
|
538
|
-
user_muc_jid.resource = self.user_nick
|
536
|
+
_, user_muc_jid = escape_nickname(self.jid, self.user_nick)
|
539
537
|
return user_muc_jid
|
540
538
|
|
541
539
|
def _legacy_to_xmpp(self, legacy_id: LegacyMessageType):
|
@@ -782,7 +780,7 @@ class LegacyMUC(
|
|
782
780
|
self.session, stored, muc=self, contact=c
|
783
781
|
)
|
784
782
|
|
785
|
-
nickname = c.name or
|
783
|
+
nickname = c.name or unescape_node(c.jid_username)
|
786
784
|
|
787
785
|
if self.pk is None:
|
788
786
|
nick_available = True
|
@@ -990,7 +988,7 @@ class LegacyMUC(
|
|
990
988
|
|
991
989
|
:param r: The resource to kick
|
992
990
|
"""
|
993
|
-
pto = self.user_jid
|
991
|
+
pto = JID(self.user_jid)
|
994
992
|
pto.resource = r
|
995
993
|
p = self.xmpp.make_presence(
|
996
994
|
pfrom=(await self.get_user_participant()).jid, pto=pto
|
@@ -0,0 +1,92 @@
|
|
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 logging
|
7
|
+
|
8
|
+
import slixmpp.plugins
|
9
|
+
import slixmpp.stanza.roster
|
10
|
+
from slixmpp import InvalidJID, Message
|
11
|
+
from slixmpp.plugins.xep_0050 import XEP_0050, Command
|
12
|
+
from slixmpp.plugins.xep_0469.stanza import NS as PINNED_NS
|
13
|
+
from slixmpp.plugins.xep_0469.stanza import Pinned
|
14
|
+
from slixmpp.xmlstream import StanzaBase
|
15
|
+
|
16
|
+
from . import (
|
17
|
+
link_preview,
|
18
|
+
xep_0077,
|
19
|
+
xep_0100,
|
20
|
+
xep_0153,
|
21
|
+
xep_0292,
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
# TODO: remove this when we pin slixmpp > 1.9.0
|
26
|
+
def get_items(self):
|
27
|
+
items = {}
|
28
|
+
for item in self["substanzas"]:
|
29
|
+
if isinstance(item, slixmpp.stanza.roster.RosterItem):
|
30
|
+
try:
|
31
|
+
items[item["jid"]] = item.values
|
32
|
+
except InvalidJID:
|
33
|
+
logging.warning("Invalid JID in roster: %s", item)
|
34
|
+
continue
|
35
|
+
del items[item["jid"]]["jid"]
|
36
|
+
del items[item["jid"]]["lang"]
|
37
|
+
return items
|
38
|
+
|
39
|
+
|
40
|
+
slixmpp.stanza.roster.Roster.get_items = get_items # type:ignore
|
41
|
+
|
42
|
+
|
43
|
+
def set_pinned(self, val: bool):
|
44
|
+
extensions = self.parent()
|
45
|
+
if val:
|
46
|
+
extensions.enable("pinned")
|
47
|
+
else:
|
48
|
+
extensions._del_sub(f"{{{PINNED_NS}}}pinned")
|
49
|
+
|
50
|
+
|
51
|
+
Pinned.set_pinned = set_pinned
|
52
|
+
|
53
|
+
|
54
|
+
def session_bind(self, jid):
|
55
|
+
self.xmpp["xep_0030"].add_feature(Command.namespace)
|
56
|
+
# awful hack to for the disco items: we need to comment this line
|
57
|
+
# related issue: https://todo.sr.ht/~nicoco/slidge/131
|
58
|
+
# self.xmpp['xep_0030'].set_items(node=Command.namespace, items=tuple())
|
59
|
+
|
60
|
+
|
61
|
+
XEP_0050.session_bind = session_bind # type:ignore
|
62
|
+
|
63
|
+
|
64
|
+
def reply(self, body=None, clear=True):
|
65
|
+
"""
|
66
|
+
Overrides slixmpp's Message.reply(), since it strips to sender's resource
|
67
|
+
for mtype=groupchat, and we do not want that, because when we raise an XMPPError,
|
68
|
+
we actually want to preserve the resource.
|
69
|
+
(this is called in RootStanza.exception() to handle XMPPErrors)
|
70
|
+
"""
|
71
|
+
new_message = StanzaBase.reply(self, clear)
|
72
|
+
new_message["thread"] = self["thread"]
|
73
|
+
new_message["parent_thread"] = self["parent_thread"]
|
74
|
+
|
75
|
+
del new_message["id"]
|
76
|
+
if self.stream is not None and self.stream.use_message_ids:
|
77
|
+
new_message["id"] = self.stream.new_id()
|
78
|
+
|
79
|
+
if body is not None:
|
80
|
+
new_message["body"] = body
|
81
|
+
return new_message
|
82
|
+
|
83
|
+
|
84
|
+
Message.reply = reply # type: ignore
|
85
|
+
|
86
|
+
|
87
|
+
slixmpp.plugins.PLUGINS.extend(
|
88
|
+
[
|
89
|
+
"link_preview",
|
90
|
+
"xep_0292_provider",
|
91
|
+
]
|
92
|
+
)
|