slidge 0.3.1__tar.gz → 0.3.3__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.3.1 → slidge-0.3.3}/PKG-INFO +1 -1
- slidge-0.3.3/docs/source/admin/config/index.rst +57 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/privilege.rst +5 -6
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/conf.py +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/pyproject.toml +3 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/user.py +22 -2
- {slidge-0.3.1 → slidge-0.3.3}/slidge/contact/contact.py +6 -13
- {slidge-0.3.1 → slidge-0.3.3}/slidge/contact/roster.py +6 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/config.py +43 -9
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/caps.py +1 -2
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/message/message.py +1 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/presence.py +1 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/registration.py +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/search.py +1 -5
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/util.py +3 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/gateway.py +12 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/attachment.py +62 -8
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/db.py +15 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/message_maker.py +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/message_text.py +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/presence.py +20 -10
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/session.py +2 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/models.py +3 -3
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/store.py +29 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge/group/room.py +17 -24
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/test.py +3 -2
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/types.py +2 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/util.py +6 -4
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/PKG-INFO +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/SOURCES.txt +1 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/conftest.py +9 -5
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_attachment.py +131 -8
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_backfill.py +0 -1
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_config.py +1 -1
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_db/test_store.py +41 -2
- slidge-0.3.3/tests/test_gateway_wide_reaction_restrictions.py +187 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_muc.py +31 -8
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_muc_subject.py +0 -4
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_session.py +0 -4
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_session_2.py +0 -4
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_set_name_before_fill.py +0 -4
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_shakespeare.py +10 -11
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_util.py +2 -2
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_vcard.py +0 -4
- slidge-0.3.3/uv.lock +2258 -0
- slidge-0.3.1/docs/source/admin/config/index.rst +0 -35
- slidge-0.3.1/uv.lock +0 -1843
- {slidge-0.3.1 → slidge-0.3.3}/.gitignore +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/.pre-commit-config.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/.woodpecker/container-ci.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/.woodpecker/docs.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/.woodpecker/package.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/.woodpecker/test.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/Dockerfile +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/LICENSE +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/README.md +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/commitlint.config.js +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/5x5.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/slidge-color-small.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/slidge-color.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/slidge-mono-black.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/slidge-mono-white.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/assets/slidge.svg +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/confs/movim.env +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/confs/nginx.conf +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/confs/slidge-dev.ini +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/confs/slidge-example.ini +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/hot-reload.sh +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/dev/prettify_tests.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/doap.xml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docker-compose.yml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/Makefile +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/attachments.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/component.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/daemon.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/examples/ejabberd.yaml +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/examples/index.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/examples/prosody.cfg.lua +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/index.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/install.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/admin/note.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/codeberg.svg +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/dev/contributing.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/dev/design.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/dev/howto.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/dev/index.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/dev/tutorial.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/glossary.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/index.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/commands.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/contacts.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/foxyproxy.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/gajim.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/index.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/low_profile.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/movim1.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/movim2.png +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/note.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/docs/source/user/register.rst +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/setup.cfg +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/__main__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/adhoc.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/admin.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/base.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/categories.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/chat_command.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/command/register.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/contact/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/disco.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/message/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/message/chat_state.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/message/marker.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/admin.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/mam.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/misc.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/owner.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/muc/ping.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/session_dispatcher.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/dispatcher/vcard.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/avatar.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/base.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/disco.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/message.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/mixins/recipient.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/core/pubsub.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/alembic/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/alembic/env.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/alembic/script.py.mako +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/avatar.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/db/meta.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/group/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/group/archive.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/group/bookmarks.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/group/participant.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/main.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/migration.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/py.typed +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/delivery_receipt.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/link_preview/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/link_preview/link_preview.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/link_preview/stanza.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/roster.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0077/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0077/register.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0077/stanza.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0100/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0100/gateway.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0100/stanza.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0153/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0292/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/slixfix/xep_0292/vcard4.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/archive_msg.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/conf.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/jid_escaping.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge/util/lock.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/dependency_links.txt +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/entry_points.txt +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/requires.txt +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/slidge.egg-info/top_level.txt +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/__init__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/__main__.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/contact.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/gateway.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/group.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/legacy_client.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/session.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/superduper/util.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_adhoc/test_access.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_adhoc/test_confirmation.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_adhoc/test_form.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_adhoc/test_reported.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_avatar.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_chat_commands.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_db/test_user.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_feature_restriction.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_mam_archivable.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_mds.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_resourceprep.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_stanza_link_preview.py +0 -0
- {slidge-0.3.1 → slidge-0.3.3}/tests/test_type_conversion.py +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Configuration
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
.. include:: ../note.rst
|
|
5
|
+
|
|
6
|
+
By default, slidge uses all config files found in ``/etc/slidge/conf.d/*``.
|
|
7
|
+
You can change this using the ``SLIDGE_CONF_DIR`` env var, eg
|
|
8
|
+
``SLIDGE_CONF_DIR=/path/dir1:/path/dir2:/path/dir3``.
|
|
9
|
+
|
|
10
|
+
It is recommended to use ``/etc/slidge/conf.d/`` to store configuration options
|
|
11
|
+
common to all slidge components (eg, attachment handling, logging options,
|
|
12
|
+
etc.), and to specify a plugin-specific file on startup, eg:
|
|
13
|
+
|
|
14
|
+
.. code-block:: bash
|
|
15
|
+
|
|
16
|
+
slidge -c /etc/slidge/superduper.conf
|
|
17
|
+
|
|
18
|
+
.. note::
|
|
19
|
+
For the debian unofficial package, just edit the ``/etc/slidge/conf.d/common.conf`` and
|
|
20
|
+
``/etc/slidge/*.conf`` files, and use :ref:`Debian packages (systemd)` to
|
|
21
|
+
launch slidge.
|
|
22
|
+
|
|
23
|
+
Command-line arguments
|
|
24
|
+
----------------------
|
|
25
|
+
|
|
26
|
+
.. code-block:: text
|
|
27
|
+
|
|
28
|
+
-h, --help show this help message and exit
|
|
29
|
+
-c, --config CONFIG Path to a INI config file. [env var: SLIDGE_CONFIG]
|
|
30
|
+
--log-config LOG_CONFIG
|
|
31
|
+
Path to a INI config file to personalise logging output.
|
|
32
|
+
-q, --quiet loglevel=WARNING (unused if --log-config is specified) [env var: SLIDGE_QUIET]
|
|
33
|
+
-d, --debug loglevel=DEBUG (unused if --log-config is specified) [env var: SLIDGE_DEBUG]
|
|
34
|
+
--version show program's version number and exit
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Regarding the ``--log-config`` argument, refer to the `official python documentation
|
|
38
|
+
<https://docs.python.org/3/library/logging.config.html#configuration-file-format>`_
|
|
39
|
+
for the syntax.
|
|
40
|
+
|
|
41
|
+
Other options
|
|
42
|
+
-------------
|
|
43
|
+
|
|
44
|
+
.. warning::
|
|
45
|
+
|
|
46
|
+
Because of an ugly mess that will soon™ be fixed, it is impossible to use
|
|
47
|
+
the config file to turn off boolean arguments that are true by default.
|
|
48
|
+
As a workaround, use CLI args instead, e.g., ``--some-opt=false``.
|
|
49
|
+
|
|
50
|
+
The following options can be used:
|
|
51
|
+
|
|
52
|
+
* in a config file (see top of this page);
|
|
53
|
+
* as command line arguments, prepended with ``--``, e.g., ``--some-option=value``;
|
|
54
|
+
* as environment variables, upper case, prepended with ``SLIDGE_``,
|
|
55
|
+
and with dashes substituted with underscores, e.g., ``SLIDGE_SOME_OPTION=value``.
|
|
56
|
+
|
|
57
|
+
.. config-obj:: slidge.core.config
|
|
@@ -79,11 +79,10 @@ Privileges with ejabberd
|
|
|
79
79
|
both: slidge_rule
|
|
80
80
|
message:
|
|
81
81
|
outgoing: slidge_rule
|
|
82
|
+
iq:
|
|
83
|
+
"http://jabber.org/protocol/pubsub":
|
|
84
|
+
both: slidge_rule
|
|
85
|
+
"http://jabber.org/protocol/pubsub#owner":
|
|
86
|
+
set: slidge_rule
|
|
82
87
|
mod_roster:
|
|
83
88
|
versioning: true
|
|
84
|
-
|
|
85
|
-
iq:
|
|
86
|
-
"http://jabber.org/protocol/pubsub":
|
|
87
|
-
both: slidge_rule
|
|
88
|
-
"http://jabber.org/protocol/pubsub#owner":
|
|
89
|
-
set: slidge_rule
|
|
@@ -39,9 +39,9 @@ extensions = [
|
|
|
39
39
|
"sphinx.ext.extlinks",
|
|
40
40
|
# "sphinx.ext.viewcode", # crashes build unfortunately
|
|
41
41
|
"sphinx.ext.autodoc.typehints",
|
|
42
|
-
"sphinx.ext.autosectionlabel",
|
|
43
42
|
"sphinxarg.ext",
|
|
44
43
|
"autoapi.extension",
|
|
44
|
+
"slidge_sphinx_extensions.config_obj",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
autodoc_typehints = "description"
|
|
@@ -63,6 +63,7 @@ dev = [
|
|
|
63
63
|
"types-pillow>=10.2.0.20240822",
|
|
64
64
|
"utidylib>=0.10",
|
|
65
65
|
"xmldiff>=2.7.0",
|
|
66
|
+
"slidge-sphinx-extensions>=0.2.1,<0.3",
|
|
66
67
|
]
|
|
67
68
|
|
|
68
69
|
[tool.mypy]
|
|
@@ -106,6 +107,8 @@ filterwarnings = [
|
|
|
106
107
|
"ignore::UserWarning:slidge",
|
|
107
108
|
"ignore:coroutine 'XMLStream._end_stream_wait' was never awaited.*:RuntimeWarning"
|
|
108
109
|
]
|
|
110
|
+
log_cli = true
|
|
111
|
+
log_level = "DEBUG"
|
|
109
112
|
|
|
110
113
|
[[tool.uv.index]]
|
|
111
114
|
name = "codeberg"
|
|
@@ -6,7 +6,7 @@ from slixmpp import JID
|
|
|
6
6
|
from slixmpp.exceptions import XMPPError
|
|
7
7
|
|
|
8
8
|
from ..group.room import LegacyMUC
|
|
9
|
-
from ..util.types import AnyBaseSession, LegacyGroupIdType, UserPreferences
|
|
9
|
+
from ..util.types import AnyBaseSession, LegacyGroupIdType, MucType, UserPreferences
|
|
10
10
|
from .base import (
|
|
11
11
|
Command,
|
|
12
12
|
CommandAccess,
|
|
@@ -157,7 +157,9 @@ class ListGroups(Command):
|
|
|
157
157
|
async def run(self, session, _ifrom, *_):
|
|
158
158
|
assert session is not None
|
|
159
159
|
await session.ready
|
|
160
|
-
groups = sorted(
|
|
160
|
+
groups = sorted(
|
|
161
|
+
session.bookmarks, key=lambda g: (g.name or g.jid.localpart).casefold()
|
|
162
|
+
)
|
|
161
163
|
return TableResult(
|
|
162
164
|
description="Your groups",
|
|
163
165
|
fields=[FormField("name"), FormField("jid", type="jid-single")],
|
|
@@ -364,3 +366,21 @@ class LeaveGroup(Command):
|
|
|
364
366
|
async def finish(session: AnyBaseSession, _ifrom, group: LegacyMUC) -> None:
|
|
365
367
|
await session.on_leave_group(group.legacy_id)
|
|
366
368
|
await session.bookmarks.remove(group, reason="You left this group via slidge.")
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
class InviteInGroups(Command):
|
|
372
|
+
NAME = "💌 Re-invite me in my groups"
|
|
373
|
+
HELP = "Ask the gateway to send invitations for all your private groups"
|
|
374
|
+
CHAT_COMMAND = "re-invite"
|
|
375
|
+
NODE = GROUPS.node + "/" + CHAT_COMMAND
|
|
376
|
+
ACCESS = CommandAccess.USER_LOGGED
|
|
377
|
+
CATEGORY = GROUPS
|
|
378
|
+
|
|
379
|
+
async def run(self, session, _ifrom, *_):
|
|
380
|
+
assert session is not None
|
|
381
|
+
await session.ready
|
|
382
|
+
for muc in session.bookmarks:
|
|
383
|
+
if muc.type == MucType.GROUP:
|
|
384
|
+
session.send_gateway_invite(
|
|
385
|
+
muc, reason="You asked to be re-invited in all groups."
|
|
386
|
+
)
|
|
@@ -120,8 +120,7 @@ class LegacyContact(
|
|
|
120
120
|
def is_friend(self, value: bool) -> None:
|
|
121
121
|
if value == self.is_friend:
|
|
122
122
|
return
|
|
123
|
-
self.
|
|
124
|
-
self.commit()
|
|
123
|
+
self.update_stored_attribute(is_friend=value)
|
|
125
124
|
|
|
126
125
|
@property
|
|
127
126
|
def added_to_roster(self) -> bool:
|
|
@@ -131,8 +130,7 @@ class LegacyContact(
|
|
|
131
130
|
def added_to_roster(self, value: bool) -> None:
|
|
132
131
|
if value == self.added_to_roster:
|
|
133
132
|
return
|
|
134
|
-
self.
|
|
135
|
-
self.commit()
|
|
133
|
+
self.update_stored_attribute(added_to_roster=value)
|
|
136
134
|
|
|
137
135
|
@property
|
|
138
136
|
def participants(self) -> Iterator["LegacyParticipant"]:
|
|
@@ -170,8 +168,7 @@ class LegacyContact(
|
|
|
170
168
|
def client_type(self, value: ClientType) -> None:
|
|
171
169
|
if self.stored.client_type == value:
|
|
172
170
|
return
|
|
173
|
-
self.
|
|
174
|
-
self.commit()
|
|
171
|
+
self.update_stored_attribute(client_type=value)
|
|
175
172
|
|
|
176
173
|
def _set_logger(self) -> None:
|
|
177
174
|
self.log = logging.getLogger(f"{self.user_jid.bare}:contact:{self}")
|
|
@@ -290,13 +287,12 @@ class LegacyContact(
|
|
|
290
287
|
def name(self, n: Optional[str]) -> None:
|
|
291
288
|
if self.stored.nick == n:
|
|
292
289
|
return
|
|
293
|
-
self.
|
|
290
|
+
self.update_stored_attribute(nick=n)
|
|
294
291
|
self._set_logger()
|
|
295
292
|
if self.is_friend and self.added_to_roster:
|
|
296
293
|
self.xmpp.pubsub.broadcast_nick(
|
|
297
294
|
user_jid=self.user_jid, jid=self.jid.bare, nick=n
|
|
298
295
|
)
|
|
299
|
-
self.commit()
|
|
300
296
|
for p in self.participants:
|
|
301
297
|
p.nickname = n or str(self.legacy_id)
|
|
302
298
|
|
|
@@ -361,14 +357,11 @@ class LegacyContact(
|
|
|
361
357
|
if pronouns:
|
|
362
358
|
vcard["pronouns"]["text"] = pronouns
|
|
363
359
|
|
|
364
|
-
self.
|
|
365
|
-
self.stored.vcard_fetched = True
|
|
360
|
+
self.update_stored_attribute(vcard=str(vcard), vcard_fetched=True)
|
|
366
361
|
self.session.create_task(
|
|
367
362
|
self.xmpp.pubsub.broadcast_vcard_event(self.jid, self.user_jid, vcard)
|
|
368
363
|
)
|
|
369
364
|
|
|
370
|
-
self.commit()
|
|
371
|
-
|
|
372
365
|
def get_roster_item(self):
|
|
373
366
|
item = {
|
|
374
367
|
"subscription": self.__get_subscription_string(),
|
|
@@ -411,7 +404,7 @@ class LegacyContact(
|
|
|
411
404
|
# we only broadcast pubsub events for contacts added to the roster
|
|
412
405
|
# so if something was set before, we need to push it now
|
|
413
406
|
self.added_to_roster = True
|
|
414
|
-
self.send_last_presence()
|
|
407
|
+
self.send_last_presence(force=True)
|
|
415
408
|
|
|
416
409
|
async def __broadcast_pubsub_items(self) -> None:
|
|
417
410
|
if not self.is_friend:
|
|
@@ -4,7 +4,7 @@ import warnings
|
|
|
4
4
|
from typing import TYPE_CHECKING, AsyncIterator, Generic, Iterator, Optional, Type
|
|
5
5
|
|
|
6
6
|
from slixmpp import JID
|
|
7
|
-
from slixmpp.exceptions import IqError, IqTimeout
|
|
7
|
+
from slixmpp.exceptions import IqError, IqTimeout, XMPPError
|
|
8
8
|
from sqlalchemy.orm import Session
|
|
9
9
|
from sqlalchemy.orm import Session as OrmSession
|
|
10
10
|
|
|
@@ -92,6 +92,10 @@ class LegacyRoster(
|
|
|
92
92
|
# :return:
|
|
93
93
|
# """
|
|
94
94
|
username = contact_jid.node
|
|
95
|
+
if not username:
|
|
96
|
+
raise XMPPError(
|
|
97
|
+
"bad-request", "Contacts must have a local part in their JID"
|
|
98
|
+
)
|
|
95
99
|
contact_jid = JID(contact_jid.bare)
|
|
96
100
|
async with self.lock(("username", username)):
|
|
97
101
|
legacy_id = await self.jid_username_to_legacy_id(username)
|
|
@@ -239,6 +243,7 @@ class LegacyRoster(
|
|
|
239
243
|
warnings.warn(f"Could not add to roster: {e}")
|
|
240
244
|
else:
|
|
241
245
|
contact.added_to_roster = True
|
|
246
|
+
contact.send_last_presence(force=True)
|
|
242
247
|
orm.commit()
|
|
243
248
|
self.__filling = False
|
|
244
249
|
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
from datetime import timedelta
|
|
2
1
|
from pathlib import Path
|
|
3
|
-
from typing import Optional
|
|
2
|
+
from typing import Optional
|
|
4
3
|
|
|
5
4
|
from slixmpp import JID as JIDType
|
|
6
5
|
|
|
6
|
+
# REQUIRED, so not default value
|
|
7
7
|
|
|
8
|
-
class _TimedeltaSeconds(timedelta):
|
|
9
|
-
def __new__(cls, s: str) -> Self:
|
|
10
|
-
return super().__new__(cls, seconds=int(s))
|
|
11
8
|
|
|
9
|
+
class _Categories:
|
|
10
|
+
MANDATORY = (0, "Mandatory settings")
|
|
11
|
+
BASE = (10, "Basic configuration")
|
|
12
|
+
ATTACHMENTS = (20, "Attachments")
|
|
13
|
+
LOG = (30, "Logging")
|
|
14
|
+
ADVANCED = (40, "Advanced settings")
|
|
12
15
|
|
|
13
|
-
# REQUIRED, so not default value
|
|
14
16
|
|
|
15
17
|
LEGACY_MODULE: str
|
|
16
18
|
LEGACY_MODULE__DOC = (
|
|
17
|
-
"Importable python module containing (at least) "
|
|
18
|
-
"
|
|
19
|
+
"Importable python module containing (at least) a BaseGateway and a LegacySession subclass. "
|
|
20
|
+
"NB: this is not needed if you use a gateway-specific entrypoint, e.g., `slidgram` or "
|
|
21
|
+
"`python -m slidgram`."
|
|
19
22
|
)
|
|
23
|
+
LEGACY_MODULE__CATEGORY = _Categories.BASE
|
|
20
24
|
|
|
21
25
|
SERVER: str = "localhost"
|
|
22
26
|
SERVER__DOC = (
|
|
@@ -27,17 +31,21 @@ SERVER__DOC = (
|
|
|
27
31
|
"you change this."
|
|
28
32
|
)
|
|
29
33
|
SERVER__SHORT = "s"
|
|
34
|
+
SERVER__CATEGORY = _Categories.BASE
|
|
30
35
|
|
|
31
36
|
SECRET: str
|
|
32
37
|
SECRET__DOC = "The gateway component's secret (required to connect to the XMPP server)"
|
|
38
|
+
SECRET__CATEGORY = _Categories.MANDATORY
|
|
33
39
|
|
|
34
40
|
JID: JIDType
|
|
35
41
|
JID__DOC = "The gateway component's JID"
|
|
36
42
|
JID__SHORT = "j"
|
|
43
|
+
JID__CATEGORY = _Categories.MANDATORY
|
|
37
44
|
|
|
38
45
|
PORT: str = "5347"
|
|
39
46
|
PORT__DOC = "The XMPP server's port for incoming component connections"
|
|
40
47
|
PORT__SHORT = "p"
|
|
48
|
+
PORT__CATEGORY = _Categories.BASE
|
|
41
49
|
|
|
42
50
|
# Dynamic default (depends on other values)
|
|
43
51
|
|
|
@@ -47,6 +55,7 @@ HOME_DIR__DOC = (
|
|
|
47
55
|
"Defaults to /var/lib/slidge/${SLIDGE_JID}. "
|
|
48
56
|
)
|
|
49
57
|
HOME_DIR__DYNAMIC_DEFAULT = True
|
|
58
|
+
HOME_DIR__CATEGORY = _Categories.BASE
|
|
50
59
|
|
|
51
60
|
DB_URL: str
|
|
52
61
|
DB_URL__DOC = (
|
|
@@ -54,6 +63,7 @@ DB_URL__DOC = (
|
|
|
54
63
|
"Defaults to sqlite:///${HOME_DIR}/slidge.sqlite"
|
|
55
64
|
)
|
|
56
65
|
DB_URL__DYNAMIC_DEFAULT = True
|
|
66
|
+
DB_URL__CATEGORY = _Categories.ADVANCED
|
|
57
67
|
|
|
58
68
|
USER_JID_VALIDATOR: str
|
|
59
69
|
USER_JID_VALIDATOR__DOC = (
|
|
@@ -62,11 +72,13 @@ USER_JID_VALIDATOR__DOC = (
|
|
|
62
72
|
"you probably want to change that to .*@example.com"
|
|
63
73
|
)
|
|
64
74
|
USER_JID_VALIDATOR__DYNAMIC_DEFAULT = True
|
|
75
|
+
USER_JID_VALIDATOR__CATEGORY = _Categories.BASE
|
|
65
76
|
|
|
66
77
|
# Optional, so default value + type hint if default is None
|
|
67
78
|
|
|
68
79
|
ADMINS: tuple[JIDType, ...] = ()
|
|
69
80
|
ADMINS__DOC = "JIDs of the gateway admins"
|
|
81
|
+
ADMINS__CATEGORY = _Categories.BASE
|
|
70
82
|
|
|
71
83
|
UPLOAD_SERVICE: Optional[str] = None
|
|
72
84
|
UPLOAD_SERVICE__DOC = (
|
|
@@ -74,11 +86,13 @@ UPLOAD_SERVICE__DOC = (
|
|
|
74
86
|
"This is optional, as it should be automatically determined via service"
|
|
75
87
|
"discovery."
|
|
76
88
|
)
|
|
89
|
+
UPLOAD_SERVICE__CATEGORY = _Categories.ATTACHMENTS
|
|
77
90
|
|
|
78
91
|
AVATAR_SIZE = 200
|
|
79
92
|
AVATAR_SIZE__DOC = (
|
|
80
93
|
"Maximum image size (width and height), image ratio will be preserved"
|
|
81
94
|
)
|
|
95
|
+
AVATAR_SIZE__CATEGORY = _Categories.ADVANCED
|
|
82
96
|
|
|
83
97
|
USE_ATTACHMENT_ORIGINAL_URLS = False
|
|
84
98
|
USE_ATTACHMENT_ORIGINAL_URLS__DOC = (
|
|
@@ -86,11 +100,13 @@ USE_ATTACHMENT_ORIGINAL_URLS__DOC = (
|
|
|
86
100
|
"let XMPP clients directly download them from this URL. Note that this will "
|
|
87
101
|
"probably leak your client IP to the legacy network."
|
|
88
102
|
)
|
|
103
|
+
USE_ATTACHMENT_ORIGINAL_URLS__CATEGORY = _Categories.ATTACHMENTS
|
|
89
104
|
|
|
90
105
|
UPLOAD_REQUESTER: Optional[str] = None
|
|
91
106
|
UPLOAD_REQUESTER__DOC = (
|
|
92
107
|
"Set which JID should request the upload slots. Defaults to the component JID."
|
|
93
108
|
)
|
|
109
|
+
UPLOAD_REQUESTER__CATEGORY = _Categories.ATTACHMENTS
|
|
94
110
|
|
|
95
111
|
NO_UPLOAD_PATH: Optional[str] = None
|
|
96
112
|
NO_UPLOAD_PATH__DOC = (
|
|
@@ -98,38 +114,45 @@ NO_UPLOAD_PATH__DOC = (
|
|
|
98
114
|
"You need to set NO_UPLOAD_URL_PREFIX too if you use this option, and configure "
|
|
99
115
|
"an web server to serve files in this dir."
|
|
100
116
|
)
|
|
117
|
+
NO_UPLOAD_PATH__CATEGORY = _Categories.ATTACHMENTS
|
|
101
118
|
|
|
102
119
|
NO_UPLOAD_URL_PREFIX: Optional[str] = None
|
|
103
120
|
NO_UPLOAD_URL_PREFIX__DOC = (
|
|
104
121
|
"Base URL that servers files in the dir set in the no-upload-path option, "
|
|
105
122
|
"eg https://example.com:666/slidge-attachments/"
|
|
106
123
|
)
|
|
124
|
+
NO_UPLOAD_URL_PREFIX__CATEGORY = _Categories.ATTACHMENTS
|
|
107
125
|
|
|
108
126
|
NO_UPLOAD_METHOD: str = "copy"
|
|
109
127
|
NO_UPLOAD_METHOD__DOC = (
|
|
110
128
|
"Whether to 'copy', 'move', 'hardlink' or 'symlink' the files in no-upload-path."
|
|
111
129
|
)
|
|
130
|
+
NO_UPLOAD_METHOD__CATEGORY = _Categories.ATTACHMENTS
|
|
112
131
|
|
|
113
132
|
NO_UPLOAD_FILE_READ_OTHERS = False
|
|
114
133
|
NO_UPLOAD_FILE_READ_OTHERS__DOC = (
|
|
115
134
|
"After writing a file in NO_UPLOAD_PATH, change its permission so that 'others' can"
|
|
116
135
|
" read it."
|
|
117
136
|
)
|
|
137
|
+
NO_UPLOAD_FILE_READ_OTHERS__CATEGORY = _Categories.ATTACHMENTS
|
|
118
138
|
|
|
119
|
-
IGNORE_DELAY_THRESHOLD =
|
|
139
|
+
IGNORE_DELAY_THRESHOLD = 300
|
|
120
140
|
IGNORE_DELAY_THRESHOLD__DOC = (
|
|
121
141
|
"Threshold, in seconds, below which the <delay> information is stripped "
|
|
122
142
|
"out of emitted stanzas."
|
|
123
143
|
)
|
|
144
|
+
IGNORE_DELAY_THRESHOLD__CATEGORY = _Categories.ADVANCED
|
|
124
145
|
|
|
125
146
|
PARTIAL_REGISTRATION_TIMEOUT = 3600
|
|
126
147
|
PARTIAL_REGISTRATION_TIMEOUT__DOC = (
|
|
127
148
|
"Timeout before registration and login. Only useful for legacy networks where "
|
|
128
149
|
"a single step registration process is not enough."
|
|
129
150
|
)
|
|
151
|
+
PARTIAL_REGISTRATION_TIMEOUT__CATEGORY = _Categories.ADVANCED
|
|
130
152
|
|
|
131
153
|
QR_TIMEOUT = 60
|
|
132
154
|
QR_TIMEOUT__DOC = "Timeout for QR code flashing confirmation."
|
|
155
|
+
QR_TIMEOUT__CATEGORY = _Categories.ADVANCED
|
|
133
156
|
|
|
134
157
|
FIX_FILENAME_SUFFIX_MIME_TYPE = False
|
|
135
158
|
FIX_FILENAME_SUFFIX_MIME_TYPE__DOC = (
|
|
@@ -138,9 +161,11 @@ FIX_FILENAME_SUFFIX_MIME_TYPE__DOC = (
|
|
|
138
161
|
" Therefore the MIME Type of the file is checked, if the suffix is not valid for"
|
|
139
162
|
" that MIME Type, a valid one will be picked."
|
|
140
163
|
)
|
|
164
|
+
FIX_FILENAME_SUFFIX_MIME_TYPE__CATEGORY = _Categories.ATTACHMENTS
|
|
141
165
|
|
|
142
166
|
LOG_FILE: Optional[Path] = None
|
|
143
167
|
LOG_FILE__DOC = "Log to a file instead of stdout/err"
|
|
168
|
+
LOG_FILE__CATEGORY = _Categories.LOG
|
|
144
169
|
|
|
145
170
|
LOG_FORMAT: str = "%(levelname)s:%(name)s:%(message)s"
|
|
146
171
|
LOG_FORMAT__DOC = (
|
|
@@ -148,41 +173,50 @@ LOG_FORMAT__DOC = (
|
|
|
148
173
|
"https://docs.python.org/3/library/logging.html#logrecord-attributes "
|
|
149
174
|
"for available options."
|
|
150
175
|
)
|
|
176
|
+
LOG_FORMAT__CATEGORY = _Categories.LOG
|
|
151
177
|
|
|
152
178
|
MAM_MAX_DAYS = 7
|
|
153
179
|
MAM_MAX_DAYS__DOC = "Maximum number of days for group archive retention."
|
|
180
|
+
MAM_MAX_DAYS__CATEGORY = _Categories.BASE
|
|
154
181
|
|
|
155
182
|
ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH = 200
|
|
156
183
|
ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__DOC = (
|
|
157
184
|
"Some legacy network provide ridiculously long filenames, strip above this limit, "
|
|
158
185
|
"preserving suffix."
|
|
159
186
|
)
|
|
187
|
+
ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__CATEGORY = _Categories.ATTACHMENTS
|
|
160
188
|
|
|
161
189
|
AVATAR_RESAMPLING_THREADS = 2
|
|
162
190
|
AVATAR_RESAMPLING_THREADS__DOC = (
|
|
163
191
|
"Number of additional threads to use for avatar resampling. Even in a single-core "
|
|
164
192
|
"context, this makes avatar resampling non-blocking."
|
|
165
193
|
)
|
|
194
|
+
AVATAR_RESAMPLING_THREADS__CATEGORY = _Categories.ADVANCED
|
|
166
195
|
|
|
167
196
|
DEV_MODE = False
|
|
168
197
|
DEV_MODE__DOC = (
|
|
169
198
|
"Enables an interactive python shell via chat commands, for admins."
|
|
170
199
|
"Not safe to use in prod, but great during dev."
|
|
171
200
|
)
|
|
201
|
+
DEV_MODE__CATEGORY = _Categories.ADVANCED
|
|
202
|
+
|
|
172
203
|
|
|
173
204
|
STRIP_LEADING_EMOJI_ADHOC = False
|
|
174
205
|
STRIP_LEADING_EMOJI_ADHOC__DOC = (
|
|
175
206
|
"Strip the leading emoji in ad-hoc command names, if present, in case you "
|
|
176
207
|
"are a emoji-hater."
|
|
177
208
|
)
|
|
209
|
+
STRIP_LEADING_EMOJI_ADHOC__CATEGORY = _Categories.ADVANCED
|
|
178
210
|
|
|
179
211
|
COMPONENT_NAME: Optional[str] = None
|
|
180
212
|
COMPONENT_NAME__DOC = (
|
|
181
213
|
"Overrides the default component name with a custom one. This is seen in service discovery and as the nickname "
|
|
182
214
|
"of the component in chat windows."
|
|
183
215
|
)
|
|
216
|
+
COMPONENT_NAME__CATEGORY = _Categories.ADVANCED
|
|
184
217
|
|
|
185
218
|
WELCOME_MESSAGE: Optional[str] = None
|
|
186
219
|
WELCOME_MESSAGE__DOC = (
|
|
187
220
|
"Overrides the default welcome message received by newly registered users."
|
|
188
221
|
)
|
|
222
|
+
WELCOME_MESSAGE__CATEGORY = _Categories.ADVANCED
|
|
@@ -57,8 +57,7 @@ class CapsMixin(DispatcherMixin):
|
|
|
57
57
|
ver = contact.stored.caps_ver
|
|
58
58
|
else:
|
|
59
59
|
ver = await contact.get_caps_ver(pfrom)
|
|
60
|
-
contact.
|
|
61
|
-
contact.commit()
|
|
60
|
+
contact.update_stored_attribute(caps_ver=ver)
|
|
62
61
|
else:
|
|
63
62
|
ver = await caps.get_verstring(pfrom)
|
|
64
63
|
|
|
@@ -3,7 +3,6 @@ from typing import TYPE_CHECKING
|
|
|
3
3
|
from slixmpp import JID, CoroutineCallback, Iq, StanzaPath
|
|
4
4
|
from slixmpp.exceptions import XMPPError
|
|
5
5
|
|
|
6
|
-
from ...db.models import GatewayUser
|
|
7
6
|
from .util import DispatcherMixin, exceptions_to_xmpp_errors
|
|
8
7
|
|
|
9
8
|
if TYPE_CHECKING:
|
|
@@ -32,10 +31,7 @@ class SearchMixin(DispatcherMixin):
|
|
|
32
31
|
"""
|
|
33
32
|
Prepare the search form using :attr:`.BaseSession.SEARCH_FIELDS`
|
|
34
33
|
"""
|
|
35
|
-
|
|
36
|
-
user = orm.query(GatewayUser).one_or_none()
|
|
37
|
-
if user is None:
|
|
38
|
-
raise XMPPError(text="Search is only allowed for registered users")
|
|
34
|
+
await self._get_session(iq)
|
|
39
35
|
|
|
40
36
|
xmpp = self.xmpp
|
|
41
37
|
|
|
@@ -172,7 +172,9 @@ def exceptions_to_xmpp_errors(cb: HandlerType) -> HandlerType:
|
|
|
172
172
|
except NotImplementedError:
|
|
173
173
|
log.debug("NotImplementedError raised in %s", cb)
|
|
174
174
|
raise XMPPError(
|
|
175
|
-
"feature-not-implemented",
|
|
175
|
+
"feature-not-implemented",
|
|
176
|
+
f"{cb.__name__} is not implemented by the legacy module",
|
|
177
|
+
clear=False,
|
|
176
178
|
)
|
|
177
179
|
except Exception as e:
|
|
178
180
|
log.error("Failed to handle incoming stanza: %s", args, exc_info=e)
|
|
@@ -330,6 +330,7 @@ class BaseGateway(
|
|
|
330
330
|
self.jid_validator: re.Pattern = re.compile(config.USER_JID_VALIDATOR)
|
|
331
331
|
self.qr_pending_registrations = dict[str, asyncio.Future[Optional[dict]]]()
|
|
332
332
|
|
|
333
|
+
self.register_plugins()
|
|
333
334
|
self.__setup_legacy_module_subclasses()
|
|
334
335
|
|
|
335
336
|
self.get_session_from_stanza: Callable[
|
|
@@ -339,7 +340,6 @@ class BaseGateway(
|
|
|
339
340
|
self._session_cls.from_user
|
|
340
341
|
)
|
|
341
342
|
|
|
342
|
-
self.register_plugins()
|
|
343
343
|
self.__register_slixmpp_events()
|
|
344
344
|
self.__register_slixmpp_api()
|
|
345
345
|
self.roster.set_backend(RosterBackend(self))
|
|
@@ -390,6 +390,16 @@ class BaseGateway(
|
|
|
390
390
|
bookmarks_cls = LegacyBookmarks.get_self_or_unique_subclass()
|
|
391
391
|
roster_cls = LegacyRoster.get_self_or_unique_subclass()
|
|
392
392
|
|
|
393
|
+
if contact_cls.REACTIONS_SINGLE_EMOJI: # type:ignore[attr-defined]
|
|
394
|
+
form = Form()
|
|
395
|
+
form["type"] = "result"
|
|
396
|
+
form.add_field(
|
|
397
|
+
"FORM_TYPE", "hidden", value="urn:xmpp:reactions:0:restrictions"
|
|
398
|
+
)
|
|
399
|
+
form.add_field("max_reactions_per_user", value="1", type="number")
|
|
400
|
+
form.add_field("scope", value="domain")
|
|
401
|
+
self.plugin["xep_0128"].add_extended_info(data=form)
|
|
402
|
+
|
|
393
403
|
session_cls.xmpp = self # type:ignore[attr-defined]
|
|
394
404
|
contact_cls.xmpp = self # type:ignore[attr-defined]
|
|
395
405
|
muc_cls.xmpp = self # type:ignore[attr-defined]
|
|
@@ -1002,6 +1012,7 @@ SLIXMPP_PLUGINS = [
|
|
|
1002
1012
|
"xep_0106", # JID Escaping
|
|
1003
1013
|
"xep_0115", # Entity capabilities
|
|
1004
1014
|
"xep_0122", # Data Forms Validation
|
|
1015
|
+
"xep_0128", # Service Discovery Extensions
|
|
1005
1016
|
"xep_0153", # vCard-Based Avatars (for MUC avatars)
|
|
1006
1017
|
"xep_0172", # User nickname
|
|
1007
1018
|
"xep_0184", # Message Delivery Receipts
|