slidge 0.3.2__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.2 → slidge-0.3.3}/PKG-INFO +1 -1
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/privilege.rst +5 -6
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/user.py +22 -2
- {slidge-0.3.2 → slidge-0.3.3}/slidge/contact/contact.py +5 -12
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/caps.py +1 -2
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/db.py +15 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/presence.py +7 -15
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/models.py +2 -2
- {slidge-0.3.2 → slidge-0.3.3}/slidge/group/room.py +12 -22
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/types.py +2 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/PKG-INFO +1 -1
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_muc.py +8 -4
- slidge-0.3.3/uv.lock +2258 -0
- slidge-0.3.2/uv.lock +0 -1859
- {slidge-0.3.2 → slidge-0.3.3}/.gitignore +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/.pre-commit-config.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/.woodpecker/container-ci.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/.woodpecker/docs.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/.woodpecker/package.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/.woodpecker/test.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/Dockerfile +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/LICENSE +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/README.md +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/commitlint.config.js +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/5x5.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/slidge-color-small.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/slidge-color.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/slidge-mono-black.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/slidge-mono-white.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/assets/slidge.svg +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/confs/movim.env +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/confs/nginx.conf +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/confs/slidge-dev.ini +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/confs/slidge-example.ini +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/hot-reload.sh +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/dev/prettify_tests.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/doap.xml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docker-compose.yml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/Makefile +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/attachments.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/component.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/config/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/daemon.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/examples/ejabberd.yaml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/examples/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/examples/prosody.cfg.lua +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/install.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/admin/note.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/codeberg.svg +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/conf.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/dev/contributing.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/dev/design.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/dev/howto.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/dev/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/dev/tutorial.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/glossary.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/commands.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/contacts.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/foxyproxy.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/gajim.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/index.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/low_profile.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/movim1.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/movim2.png +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/note.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/docs/source/user/register.rst +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/pyproject.toml +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/setup.cfg +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/__main__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/adhoc.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/admin.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/base.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/categories.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/chat_command.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/command/register.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/contact/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/contact/roster.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/config.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/disco.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/message/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/message/chat_state.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/message/marker.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/message/message.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/admin.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/mam.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/misc.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/owner.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/muc/ping.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/presence.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/registration.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/search.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/session_dispatcher.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/util.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/dispatcher/vcard.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/gateway.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/attachment.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/avatar.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/base.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/disco.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/message.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/message_maker.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/message_text.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/mixins/recipient.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/pubsub.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/core/session.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/alembic/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/alembic/env.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/alembic/script.py.mako +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/avatar.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/meta.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/db/store.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/group/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/group/archive.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/group/bookmarks.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/group/participant.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/main.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/migration.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/py.typed +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/delivery_receipt.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/link_preview/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/link_preview/link_preview.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/link_preview/stanza.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/roster.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0077/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0077/register.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0077/stanza.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0100/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0100/gateway.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0100/stanza.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0153/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0292/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/slixfix/xep_0292/vcard4.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/archive_msg.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/conf.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/jid_escaping.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/lock.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/test.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge/util/util.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/SOURCES.txt +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/dependency_links.txt +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/entry_points.txt +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/requires.txt +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/slidge.egg-info/top_level.txt +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/__init__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/__main__.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/contact.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/gateway.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/group.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/legacy_client.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/session.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/superduper/util.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/conftest.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_adhoc/test_access.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_adhoc/test_confirmation.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_adhoc/test_form.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_adhoc/test_reported.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_attachment.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_avatar.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_backfill.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_chat_commands.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_config.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_db/test_store.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_db/test_user.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_feature_restriction.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_gateway_wide_reaction_restrictions.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_mam_archivable.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_mds.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_muc_subject.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_resourceprep.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_session.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_session_2.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_set_name_before_fill.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_shakespeare.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_stanza_link_preview.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_type_conversion.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_util.py +0 -0
- {slidge-0.3.2 → slidge-0.3.3}/tests/test_vcard.py +0 -0
|
@@ -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
|
|
@@ -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(),
|
|
@@ -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
|
|
|
@@ -2,6 +2,8 @@ import logging
|
|
|
2
2
|
import typing
|
|
3
3
|
from contextlib import contextmanager
|
|
4
4
|
|
|
5
|
+
import sqlalchemy as sa
|
|
6
|
+
|
|
5
7
|
from ...db.models import Base, Contact, Room
|
|
6
8
|
|
|
7
9
|
if typing.TYPE_CHECKING:
|
|
@@ -86,3 +88,16 @@ class UpdateInfoMixin(DBMixin):
|
|
|
86
88
|
else:
|
|
87
89
|
self.stored.extra_attributes = self.serialize_extra_attributes()
|
|
88
90
|
super().commit(merge=merge)
|
|
91
|
+
|
|
92
|
+
def update_stored_attribute(self, **kwargs) -> None:
|
|
93
|
+
for key, value in kwargs.items():
|
|
94
|
+
setattr(self.stored, key, value)
|
|
95
|
+
if self._updating_info:
|
|
96
|
+
return
|
|
97
|
+
with self.xmpp.store.session() as orm:
|
|
98
|
+
orm.execute(
|
|
99
|
+
sa.update(self.stored.__class__)
|
|
100
|
+
.where(self.stored.__class__.id == self.stored.id)
|
|
101
|
+
.values(**kwargs)
|
|
102
|
+
)
|
|
103
|
+
orm.commit()
|
|
@@ -96,22 +96,14 @@ class PresenceMixin(BaseSender, DBMixin):
|
|
|
96
96
|
)
|
|
97
97
|
|
|
98
98
|
def _store_last_presence(self, new: CachedPresence) -> None:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
stored_contact.cached_presence = True
|
|
103
|
-
for k, v in new._asdict().items():
|
|
104
|
-
setattr(stored_contact, k, v)
|
|
105
|
-
if self.__is_contact() and self._updating_info:
|
|
99
|
+
if self.__is_contact():
|
|
100
|
+
contact = self
|
|
101
|
+
elif (contact := getattr(self, "contact", None)) is None: # type:ignore[assignment]
|
|
106
102
|
return
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
stored_contact = orm.merge(stored_contact)
|
|
112
|
-
orm.add(stored_contact)
|
|
113
|
-
|
|
114
|
-
orm.commit()
|
|
103
|
+
contact.update_stored_attribute( # type:ignore[attr-defined]
|
|
104
|
+
cached_presence=True,
|
|
105
|
+
**new._asdict(),
|
|
106
|
+
)
|
|
115
107
|
|
|
116
108
|
def _make_presence(
|
|
117
109
|
self,
|
|
@@ -9,7 +9,7 @@ from slixmpp.types import MucAffiliation, MucRole
|
|
|
9
9
|
from sqlalchemy import JSON, ForeignKey, Index, UniqueConstraint
|
|
10
10
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
11
11
|
|
|
12
|
-
from ..util.types import ClientType, MucType
|
|
12
|
+
from ..util.types import ClientType, Hat, MucType
|
|
13
13
|
from .meta import Base, JSONSerializable, JSONSerializableTypes
|
|
14
14
|
|
|
15
15
|
|
|
@@ -344,7 +344,7 @@ class Participant(Base):
|
|
|
344
344
|
nickname: Mapped[str] = mapped_column(nullable=False, default=None)
|
|
345
345
|
nickname_no_illegal: Mapped[str] = mapped_column(nullable=False, default=None)
|
|
346
346
|
|
|
347
|
-
hats: Mapped[list[
|
|
347
|
+
hats: Mapped[list[Hat]] = mapped_column(JSON, default=list)
|
|
348
348
|
|
|
349
349
|
extra_attributes: Mapped[Optional[JSONSerializable]] = mapped_column(default=None)
|
|
350
350
|
|
|
@@ -169,8 +169,7 @@ class LegacyMUC(
|
|
|
169
169
|
def type(self, type_: MucType) -> None:
|
|
170
170
|
if self.type == type_:
|
|
171
171
|
return
|
|
172
|
-
self.
|
|
173
|
-
self.commit()
|
|
172
|
+
self.update_stored_attribute(muc_type=type_)
|
|
174
173
|
|
|
175
174
|
@property
|
|
176
175
|
def n_participants(self):
|
|
@@ -180,8 +179,7 @@ class LegacyMUC(
|
|
|
180
179
|
def n_participants(self, n_participants: Optional[int]) -> None:
|
|
181
180
|
if self.stored.n_participants == n_participants:
|
|
182
181
|
return
|
|
183
|
-
self.
|
|
184
|
-
self.commit()
|
|
182
|
+
self.update_stored_attribute(n_participants=n_participants)
|
|
185
183
|
|
|
186
184
|
@property
|
|
187
185
|
def user_jid(self):
|
|
@@ -203,8 +201,7 @@ class LegacyMUC(
|
|
|
203
201
|
def subject_date(self, when: Optional[datetime]) -> None:
|
|
204
202
|
if self.subject_date == when:
|
|
205
203
|
return
|
|
206
|
-
self.
|
|
207
|
-
self.commit()
|
|
204
|
+
self.update_stored_attribute(subject_date=when)
|
|
208
205
|
|
|
209
206
|
def __send_configuration_change(self, codes) -> None:
|
|
210
207
|
part = self.get_system_participant()
|
|
@@ -222,18 +219,16 @@ class LegacyMUC(
|
|
|
222
219
|
def user_nick(self, nick: str) -> None:
|
|
223
220
|
if nick == self.user_nick:
|
|
224
221
|
return
|
|
225
|
-
self.
|
|
226
|
-
self.commit()
|
|
222
|
+
self.update_stored_attribute(user_nick=nick)
|
|
227
223
|
|
|
228
224
|
def add_user_resource(self, resource: str) -> None:
|
|
229
225
|
stored_set = self.get_user_resources()
|
|
230
226
|
if resource in stored_set:
|
|
231
227
|
return
|
|
232
228
|
stored_set.add(resource)
|
|
233
|
-
self.
|
|
234
|
-
json.dumps(list(stored_set)) if stored_set else None
|
|
229
|
+
self.update_stored_attribute(
|
|
230
|
+
user_resources=(json.dumps(list(stored_set)) if stored_set else None)
|
|
235
231
|
)
|
|
236
|
-
self.commit()
|
|
237
232
|
|
|
238
233
|
def get_user_resources(self) -> set[str]:
|
|
239
234
|
stored_str = self.stored.user_resources
|
|
@@ -246,10 +241,9 @@ class LegacyMUC(
|
|
|
246
241
|
if resource not in stored_set:
|
|
247
242
|
return
|
|
248
243
|
stored_set.remove(resource)
|
|
249
|
-
self.
|
|
250
|
-
json.dumps(list(stored_set)) if stored_set else None
|
|
244
|
+
self.update_stored_attribute(
|
|
245
|
+
user_resources=(json.dumps(list(stored_set)) if stored_set else None)
|
|
251
246
|
)
|
|
252
|
-
self.commit()
|
|
253
247
|
|
|
254
248
|
@asynccontextmanager
|
|
255
249
|
async def lock(self, id_: str) -> AsyncIterator[None]:
|
|
@@ -346,8 +340,7 @@ class LegacyMUC(
|
|
|
346
340
|
def name(self, n: str | None) -> None:
|
|
347
341
|
if self.name == n:
|
|
348
342
|
return
|
|
349
|
-
self.
|
|
350
|
-
self.commit()
|
|
343
|
+
self.update_stored_attribute(name=n)
|
|
351
344
|
self._set_logger()
|
|
352
345
|
self.__send_configuration_change((104,))
|
|
353
346
|
|
|
@@ -359,8 +352,7 @@ class LegacyMUC(
|
|
|
359
352
|
def description(self, d: str) -> None:
|
|
360
353
|
if self.description == d:
|
|
361
354
|
return
|
|
362
|
-
self.
|
|
363
|
-
self.commit()
|
|
355
|
+
self.update_stored_attribute(description=d)
|
|
364
356
|
self.__send_configuration_change((104,))
|
|
365
357
|
|
|
366
358
|
def on_presence_unavailable(self, p: Presence) -> None:
|
|
@@ -440,8 +432,7 @@ class LegacyMUC(
|
|
|
440
432
|
if s == self.subject:
|
|
441
433
|
return
|
|
442
434
|
|
|
443
|
-
self.
|
|
444
|
-
self.commit()
|
|
435
|
+
self.update_stored_attribute(subject=s)
|
|
445
436
|
self.__get_subject_setter_participant().set_room_subject(
|
|
446
437
|
s, None, self.subject_date, False
|
|
447
438
|
)
|
|
@@ -464,8 +455,7 @@ class LegacyMUC(
|
|
|
464
455
|
if subject_setter == self.subject_setter:
|
|
465
456
|
return
|
|
466
457
|
assert isinstance(subject_setter, str | None)
|
|
467
|
-
self.
|
|
468
|
-
self.commit()
|
|
458
|
+
self.update_stored_attribute(subject_setter=subject_setter)
|
|
469
459
|
|
|
470
460
|
def __get_subject_setter_participant(self) -> LegacyParticipant:
|
|
471
461
|
if self.subject_setter is None:
|
|
@@ -4525,9 +4525,11 @@ class TestHats(Base):
|
|
|
4525
4525
|
</x>
|
|
4526
4526
|
<hats xmlns="urn:xmpp:hats:0">
|
|
4527
4527
|
<hat uri="uri1"
|
|
4528
|
-
title="title1"
|
|
4528
|
+
title="title1"
|
|
4529
|
+
hue="0.0" />
|
|
4529
4530
|
<hat uri="uri2"
|
|
4530
|
-
title="title2"
|
|
4531
|
+
title="title2"
|
|
4532
|
+
hue="0.0" />
|
|
4531
4533
|
</hats>
|
|
4532
4534
|
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
|
4533
4535
|
id="uuid" />
|
|
@@ -4546,9 +4548,11 @@ class TestHats(Base):
|
|
|
4546
4548
|
</x>
|
|
4547
4549
|
<hats xmlns="urn:xmpp:hats:0">
|
|
4548
4550
|
<hat uri="uri1"
|
|
4549
|
-
title="title1"
|
|
4551
|
+
title="title1"
|
|
4552
|
+
hue="0.0" />
|
|
4550
4553
|
<hat uri="uri3"
|
|
4551
|
-
title="title3"
|
|
4554
|
+
title="title3"
|
|
4555
|
+
hue="0.0" />
|
|
4552
4556
|
</hats>
|
|
4553
4557
|
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
|
4554
4558
|
id="uuid" />
|