slidge 0.2.1__py3-none-any.whl → 0.2.3.post1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- slidge/__version__.py +1 -1
- slidge/command/base.py +1 -1
- slidge/command/chat_command.py +5 -2
- slidge/command/register.py +2 -4
- slidge/command/user.py +1 -1
- slidge/contact/contact.py +1 -1
- slidge/core/dispatcher/muc/admin.py +3 -4
- slidge/core/dispatcher/presence.py +3 -3
- slidge/core/gateway.py +3 -0
- slidge/core/mixins/attachment.py +13 -2
- slidge/core/mixins/avatar.py +6 -0
- slidge/core/mixins/message.py +13 -2
- slidge/db/models.py +4 -0
- slidge/db/store.py +9 -3
- slidge/group/archive.py +3 -3
- slidge/group/participant.py +11 -5
- slidge/main.py +1 -1
- slidge/slixfix/__init__.py +5 -16
- slidge/slixfix/xep_0153/__init__.py +0 -1
- slidge/slixfix/xep_0153/vcard_avatar.py +1 -10
- slidge/util/test.py +9 -2
- slidge-0.2.3.post1.dist-info/METADATA +793 -0
- {slidge-0.2.1.dist-info → slidge-0.2.3.post1.dist-info}/RECORD +38 -54
- {slidge-0.2.1.dist-info → slidge-0.2.3.post1.dist-info}/WHEEL +2 -1
- slidge-0.2.3.post1.dist-info/entry_points.txt +2 -0
- slidge-0.2.3.post1.dist-info/top_level.txt +1 -0
- slidge/slixfix/xep_0153/stanza.py +0 -25
- slidge/slixfix/xep_0264/__init__.py +0 -5
- slidge/slixfix/xep_0264/stanza.py +0 -36
- slidge/slixfix/xep_0264/thumbnail.py +0 -23
- slidge/slixfix/xep_0313/__init__.py +0 -12
- slidge/slixfix/xep_0313/mam.py +0 -262
- slidge/slixfix/xep_0313/stanza.py +0 -359
- slidge/slixfix/xep_0317/__init__.py +0 -5
- slidge/slixfix/xep_0317/hats.py +0 -17
- slidge/slixfix/xep_0317/stanza.py +0 -28
- slidge/slixfix/xep_0424/__init__.py +0 -9
- slidge/slixfix/xep_0424/retraction.py +0 -77
- slidge/slixfix/xep_0424/stanza.py +0 -28
- slidge/slixfix/xep_0490/__init__.py +0 -8
- slidge/slixfix/xep_0490/mds.py +0 -47
- slidge/slixfix/xep_0490/stanza.py +0 -17
- slidge-0.2.1.dist-info/LICENSE +0 -661
- slidge-0.2.1.dist-info/METADATA +0 -116
- slidge-0.2.1.dist-info/entry_points.txt +0 -3
slidge/__version__.py
CHANGED
slidge/command/base.py
CHANGED
slidge/command/chat_command.py
CHANGED
@@ -175,7 +175,9 @@ class ChatCommandProvider:
|
|
175
175
|
else:
|
176
176
|
if f.type == "list-multi":
|
177
177
|
msg.reply(
|
178
|
-
"Multiple selection allowed, use
|
178
|
+
"Multiple selection allowed, use new lines as a separator, ie, "
|
179
|
+
"one selected item per line. To select no item, reply with a space "
|
180
|
+
"(the punctuation)."
|
179
181
|
).send()
|
180
182
|
if f.options:
|
181
183
|
for o in f.options:
|
@@ -202,7 +204,8 @@ class ChatCommandProvider:
|
|
202
204
|
ans = "false"
|
203
205
|
|
204
206
|
if f.type.endswith("multi"):
|
205
|
-
|
207
|
+
choices = [] if ans == " " else ans.split("\n")
|
208
|
+
form_values[f.var] = f.validate(choices)
|
206
209
|
else:
|
207
210
|
form_values[f.var] = f.validate(ans)
|
208
211
|
result = await self.__wrap_handler(
|
slidge/command/register.py
CHANGED
@@ -98,7 +98,7 @@ class Register(Command):
|
|
98
98
|
raise
|
99
99
|
|
100
100
|
user = GatewayUser(
|
101
|
-
jid=ifrom.bare,
|
101
|
+
jid=JID(ifrom.bare),
|
102
102
|
legacy_module_data=form_values if data is None else data,
|
103
103
|
)
|
104
104
|
|
@@ -119,9 +119,7 @@ class Register(Command):
|
|
119
119
|
elif self.xmpp.REGISTRATION_TYPE == RegistrationType.QRCODE:
|
120
120
|
self.xmpp.qr_pending_registrations[ # type:ignore
|
121
121
|
user.jid.bare
|
122
|
-
] = (
|
123
|
-
self.xmpp.loop.create_future()
|
124
|
-
)
|
122
|
+
] = self.xmpp.loop.create_future()
|
125
123
|
qr_text = await self.xmpp.get_qr_text(user)
|
126
124
|
qr = qrcode.make(qr_text)
|
127
125
|
with tempfile.NamedTemporaryFile(
|
slidge/command/user.py
CHANGED
@@ -292,7 +292,7 @@ class Unregister(Command):
|
|
292
292
|
user = self.xmpp.store.users.get(session.user_jid)
|
293
293
|
assert user is not None
|
294
294
|
await self.xmpp.unregister_user(user)
|
295
|
-
return "
|
295
|
+
return "You are not registered anymore. Bye!"
|
296
296
|
|
297
297
|
|
298
298
|
class LeaveGroup(Command):
|
slidge/contact/contact.py
CHANGED
@@ -454,7 +454,7 @@ class LegacyContact(
|
|
454
454
|
except PermissionError:
|
455
455
|
warnings.warn(
|
456
456
|
"Slidge does not have privileges to add contacts to the roster. Refer"
|
457
|
-
" to https://slidge.
|
457
|
+
" to https://slidge.codeberg.page/docs/main/admin/privilege.html for"
|
458
458
|
" more info."
|
459
459
|
)
|
460
460
|
if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
|
@@ -11,7 +11,7 @@ class MucAdminMixin(DispatcherMixin):
|
|
11
11
|
self.xmpp.register_handler(
|
12
12
|
CoroutineCallback(
|
13
13
|
"MUCModerate",
|
14
|
-
StanzaPath("iq/
|
14
|
+
StanzaPath("iq/moderate"),
|
15
15
|
self.on_user_moderation,
|
16
16
|
)
|
17
17
|
)
|
@@ -35,12 +35,11 @@ class MucAdminMixin(DispatcherMixin):
|
|
35
35
|
assert isinstance(iq, Iq)
|
36
36
|
muc = await self.get_muc_from_stanza(iq)
|
37
37
|
|
38
|
-
|
39
|
-
xmpp_id =
|
38
|
+
moderate = iq["moderate"]
|
39
|
+
xmpp_id = iq["moderate"]["id"]
|
40
40
|
if not xmpp_id:
|
41
41
|
raise XMPPError("bad-request", "Missing moderated message ID")
|
42
42
|
|
43
|
-
moderate = apply_to["moderate"]
|
44
43
|
if not moderate["retract"]:
|
45
44
|
raise XMPPError(
|
46
45
|
"feature-not-implemented",
|
@@ -165,9 +165,9 @@ class PresenceHandlerMixin(DispatcherMixin):
|
|
165
165
|
error_stanza["error"]["type"] = "cancel"
|
166
166
|
error_stanza["error"]["by"] = muc.jid
|
167
167
|
error_stanza["error"]["condition"] = "not-acceptable"
|
168
|
-
error_stanza["error"][
|
169
|
-
"
|
170
|
-
|
168
|
+
error_stanza["error"]["text"] = (
|
169
|
+
"Slidge does not let you change your nickname in groups."
|
170
|
+
)
|
171
171
|
error_stanza.send()
|
172
172
|
|
173
173
|
|
slidge/core/gateway.py
CHANGED
@@ -797,6 +797,9 @@ class BaseGateway(
|
|
797
797
|
fut.set_exception(exception)
|
798
798
|
|
799
799
|
async def unregister_user(self, user: GatewayUser):
|
800
|
+
self.send_presence(
|
801
|
+
pshow="busy", pstatus="You are not registered to this gateway anymore."
|
802
|
+
)
|
800
803
|
await self.xmpp.plugin["xep_0077"].api["user_remove"](None, None, user.jid)
|
801
804
|
await self.xmpp.session_cls.kill_by_jid(user.jid)
|
802
805
|
|
slidge/core/mixins/attachment.py
CHANGED
@@ -20,11 +20,11 @@ import thumbhash
|
|
20
20
|
from PIL import Image, ImageOps
|
21
21
|
from slixmpp import JID, Message
|
22
22
|
from slixmpp.exceptions import IqError, IqTimeout
|
23
|
+
from slixmpp.plugins.xep_0264.stanza import Thumbnail
|
23
24
|
from slixmpp.plugins.xep_0363 import FileUploadError
|
24
25
|
from slixmpp.plugins.xep_0447.stanza import StatelessFileSharing
|
25
26
|
|
26
27
|
from ...db.avatar import avatar_cache
|
27
|
-
from ...slixfix.xep_0264.stanza import Thumbnail
|
28
28
|
from ...util.types import (
|
29
29
|
LegacyAttachment,
|
30
30
|
LegacyMessageType,
|
@@ -374,9 +374,20 @@ class AttachmentMixin(TextMessageMixin):
|
|
374
374
|
if xmpp_id == original_xmpp_id:
|
375
375
|
continue
|
376
376
|
self.retract(xmpp_id, thread)
|
377
|
+
|
378
|
+
if reply_to is not None and reply_to.body:
|
379
|
+
# We cannot have a "quote fallback" for attachments since most (all?)
|
380
|
+
# XMPP clients will only treat a message as an attachment if the
|
381
|
+
# body is the URL and nothing else.
|
382
|
+
reply_to_for_attachment: MessageReference | None = MessageReference(
|
383
|
+
reply_to.legacy_id, reply_to.author
|
384
|
+
)
|
385
|
+
else:
|
386
|
+
reply_to_for_attachment = reply_to
|
387
|
+
|
377
388
|
msg = self._make_message(
|
378
389
|
when=when,
|
379
|
-
reply_to=
|
390
|
+
reply_to=reply_to_for_attachment,
|
380
391
|
carbon=carbon,
|
381
392
|
mto=mto,
|
382
393
|
thread=thread,
|
slidge/core/mixins/avatar.py
CHANGED
@@ -3,6 +3,7 @@ from hashlib import sha1
|
|
3
3
|
from pathlib import Path
|
4
4
|
from typing import TYPE_CHECKING, Optional
|
5
5
|
|
6
|
+
from PIL import UnidentifiedImageError
|
6
7
|
from slixmpp import JID
|
7
8
|
|
8
9
|
from ...db.avatar import CachedAvatar, avatar_cache
|
@@ -100,6 +101,11 @@ class AvatarMixin:
|
|
100
101
|
else:
|
101
102
|
try:
|
102
103
|
cached_avatar = await avatar_cache.convert_or_get(a)
|
104
|
+
except UnidentifiedImageError:
|
105
|
+
self.session.log.warning("%s is not a valid avatar", a)
|
106
|
+
self._avatar_pk = None
|
107
|
+
self.__avatar_unique_id = uid
|
108
|
+
return
|
103
109
|
except Exception as e:
|
104
110
|
self.session.log.error("Failed to set avatar %s", a, exc_info=e)
|
105
111
|
self._avatar_pk = None
|
slidge/core/mixins/message.py
CHANGED
@@ -4,8 +4,8 @@ import warnings
|
|
4
4
|
from typing import TYPE_CHECKING, Optional
|
5
5
|
|
6
6
|
from slixmpp import Iq, Message
|
7
|
+
from slixmpp.plugins.xep_0004 import Form
|
7
8
|
|
8
|
-
from ...slixfix.xep_0490.mds import PUBLISH_OPTIONS
|
9
9
|
from ...util.types import ChatState, LegacyMessageType, Marker
|
10
10
|
from .attachment import AttachmentMixin
|
11
11
|
from .message_maker import MessageMaker
|
@@ -14,6 +14,17 @@ from .message_text import TextMessageMixin
|
|
14
14
|
if TYPE_CHECKING:
|
15
15
|
from ...group import LegacyMUC
|
16
16
|
|
17
|
+
# this is for MDS
|
18
|
+
PUBLISH_OPTIONS = Form()
|
19
|
+
PUBLISH_OPTIONS["type"] = "submit"
|
20
|
+
PUBLISH_OPTIONS.add_field(
|
21
|
+
"FORM_TYPE", "hidden", value="http://jabber.org/protocol/pubsub#publish-options"
|
22
|
+
)
|
23
|
+
PUBLISH_OPTIONS.add_field("pubsub#persist_items", value="true")
|
24
|
+
PUBLISH_OPTIONS.add_field("pubsub#max_items", value="max")
|
25
|
+
PUBLISH_OPTIONS.add_field("pubsub#send_last_published_item", value="never")
|
26
|
+
PUBLISH_OPTIONS.add_field("pubsub#access_model", value="whitelist")
|
27
|
+
|
17
28
|
|
18
29
|
class ChatStateMixin(MessageMaker):
|
19
30
|
def __init__(self):
|
@@ -172,7 +183,7 @@ class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
|
|
172
183
|
warnings.warn(
|
173
184
|
"Slidge does not have privileges to send message on behalf of"
|
174
185
|
" user.Refer to"
|
175
|
-
" https://slidge.
|
186
|
+
" https://slidge.codeberg.page/docs/main/admin/privilege.html"
|
176
187
|
" for more info."
|
177
188
|
)
|
178
189
|
|
slidge/db/models.py
CHANGED
@@ -242,6 +242,10 @@ class Room(Base):
|
|
242
242
|
|
243
243
|
avatar_legacy_id: Mapped[Optional[str]] = mapped_column(nullable=True)
|
244
244
|
|
245
|
+
archive: Mapped[list["ArchivedMessage"]] = relationship(
|
246
|
+
cascade="all, delete-orphan"
|
247
|
+
)
|
248
|
+
|
245
249
|
|
246
250
|
class ArchivedMessage(Base):
|
247
251
|
"""
|
slidge/db/store.py
CHANGED
@@ -18,9 +18,16 @@ from sqlalchemy.sql.functions import count
|
|
18
18
|
|
19
19
|
from ..core import config
|
20
20
|
from ..util.archive_msg import HistoryMessage
|
21
|
-
from ..util.types import
|
21
|
+
from ..util.types import (
|
22
|
+
URL,
|
23
|
+
CachedPresence,
|
24
|
+
ClientType,
|
25
|
+
MamMetadata,
|
26
|
+
MucAffiliation,
|
27
|
+
MucRole,
|
28
|
+
Sticker,
|
29
|
+
)
|
22
30
|
from ..util.types import Hat as HatTuple
|
23
|
-
from ..util.types import MamMetadata, MucAffiliation, MucRole, Sticker
|
24
31
|
from .meta import Base
|
25
32
|
from .models import (
|
26
33
|
ArchivedMessage,
|
@@ -545,7 +552,6 @@ class MAMStore(EngineMixin):
|
|
545
552
|
sender: Optional[str] = None,
|
546
553
|
flip=False,
|
547
554
|
) -> Iterator[HistoryMessage]:
|
548
|
-
|
549
555
|
with self.session() as session:
|
550
556
|
q = select(ArchivedMessage).where(ArchivedMessage.room_id == room_pk)
|
551
557
|
if start_date is not None:
|
slidge/group/archive.py
CHANGED
@@ -49,9 +49,9 @@ class MessageArchive:
|
|
49
49
|
new_msg["muc"]["jid"] = participant.muc.jid
|
50
50
|
else:
|
51
51
|
log.warning("No real JID for participant in this group")
|
52
|
-
new_msg["muc"][
|
53
|
-
"
|
54
|
-
|
52
|
+
new_msg["muc"]["jid"] = (
|
53
|
+
f"{uuid.uuid4()}@{participant.xmpp.boundjid.bare}"
|
54
|
+
)
|
55
55
|
|
56
56
|
self.__store.add_message(
|
57
57
|
self.room_pk,
|
slidge/group/participant.py
CHANGED
@@ -322,7 +322,10 @@ class LegacyParticipant(
|
|
322
322
|
legacy_msg_id=None,
|
323
323
|
**send_kwargs,
|
324
324
|
) -> MessageOrPresenceTypeVar:
|
325
|
-
stanza
|
325
|
+
if stanza.get_from().resource:
|
326
|
+
stanza["occupant-id"]["id"] = self.__occupant_id
|
327
|
+
else:
|
328
|
+
stanza["occupant-id"]["id"] = "room"
|
326
329
|
self.__add_nick_element(stanza)
|
327
330
|
if not self.is_user and isinstance(stanza, Presence):
|
328
331
|
if stanza["type"] == "unavailable" and not self._presence_sent:
|
@@ -459,11 +462,14 @@ class LegacyParticipant(
|
|
459
462
|
|
460
463
|
for i in msg_ids:
|
461
464
|
m = self.muc.get_system_participant()._make_message()
|
462
|
-
m["
|
463
|
-
|
464
|
-
|
465
|
+
m["retract"]["id"] = i
|
466
|
+
if self.is_system:
|
467
|
+
m["retract"].enable("moderated")
|
468
|
+
else:
|
469
|
+
m["retract"]["moderated"]["by"] = self.jid
|
470
|
+
m["retract"]["moderated"]["occupant-id"]["id"] = self.__occupant_id
|
465
471
|
if reason:
|
466
|
-
m["
|
472
|
+
m["retract"]["reason"] = reason
|
467
473
|
self._send(m)
|
468
474
|
|
469
475
|
def set_room_subject(
|
slidge/main.py
CHANGED
@@ -10,7 +10,7 @@ Use the long version of the CLI arg without the double dash prefix inside this
|
|
10
10
|
INI file, eg ``debug=true``.
|
11
11
|
|
12
12
|
An example configuration file is available at
|
13
|
-
https://
|
13
|
+
https://codeberg.org/slidge/slidge/src/branch/main/dev/confs/slidge-example.ini
|
14
14
|
"""
|
15
15
|
|
16
16
|
import asyncio
|
slidge/slixfix/__init__.py
CHANGED
@@ -8,21 +8,13 @@ from slixmpp import Iq, Message
|
|
8
8
|
from slixmpp.exceptions import XMPPError
|
9
9
|
from slixmpp.plugins.xep_0050 import XEP_0050, Command
|
10
10
|
from slixmpp.plugins.xep_0231 import XEP_0231
|
11
|
+
from slixmpp.plugins.xep_0425.stanza import Moderate
|
11
12
|
from slixmpp.xmlstream import StanzaBase
|
12
13
|
|
13
|
-
from . import
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
xep_0153,
|
18
|
-
xep_0264,
|
19
|
-
xep_0292,
|
20
|
-
xep_0313,
|
21
|
-
xep_0317,
|
22
|
-
xep_0356_old,
|
23
|
-
xep_0424,
|
24
|
-
xep_0490,
|
25
|
-
)
|
14
|
+
from . import link_preview, xep_0077, xep_0100, xep_0153, xep_0292, xep_0356_old
|
15
|
+
|
16
|
+
# TODO: remove this when the fix is included in slixmpp
|
17
|
+
Moderate.interfaces.add("id")
|
26
18
|
|
27
19
|
|
28
20
|
async def _handle_bob_iq(self, iq: Iq):
|
@@ -86,11 +78,8 @@ def reply(self, body=None, clear=True):
|
|
86
78
|
slixmpp.plugins.PLUGINS.extend(
|
87
79
|
[
|
88
80
|
"link_preview",
|
89
|
-
"xep_0264",
|
90
81
|
"xep_0292_provider",
|
91
|
-
"xep_0317",
|
92
82
|
"xep_0356_old",
|
93
|
-
"xep_0490",
|
94
83
|
]
|
95
84
|
)
|
96
85
|
|
@@ -1,17 +1,8 @@
|
|
1
|
-
# Slixmpp: The Slick XMPP Library
|
2
|
-
# Copyright (C) 2012 Nathanael C. Fritz, Lance J.T. Stout
|
3
|
-
# This file is part of Slixmpp.
|
4
|
-
# See the file LICENSE for copying permission.
|
5
|
-
import logging
|
6
|
-
|
7
1
|
from slixmpp.plugins.base import BasePlugin
|
2
|
+
from slixmpp.plugins.xep_0153 import VCardTempUpdate, stanza
|
8
3
|
from slixmpp.stanza import Presence
|
9
4
|
from slixmpp.xmlstream import register_stanza_plugin
|
10
5
|
|
11
|
-
from . import VCardTempUpdate, stanza
|
12
|
-
|
13
|
-
log = logging.getLogger(__name__)
|
14
|
-
|
15
6
|
|
16
7
|
class XEP_0153(BasePlugin):
|
17
8
|
name = "xep_0153"
|
slidge/util/test.py
CHANGED
@@ -5,7 +5,14 @@ from pathlib import Path
|
|
5
5
|
from typing import Optional, Union
|
6
6
|
from xml.dom.minidom import parseString
|
7
7
|
|
8
|
-
|
8
|
+
try:
|
9
|
+
import xmldiff.main
|
10
|
+
|
11
|
+
XML_DIFF_PRESENT = True
|
12
|
+
except ImportError:
|
13
|
+
xmldiff = None
|
14
|
+
XML_DIFF_PRESENT = False
|
15
|
+
|
9
16
|
from slixmpp import (
|
10
17
|
JID,
|
11
18
|
ElementBase,
|
@@ -157,7 +164,7 @@ class SlixTestPlus(SlixTest):
|
|
157
164
|
result = self.compare(xml, stanza.xml, stanza2.xml)
|
158
165
|
stanza_class.namespace = old_ns
|
159
166
|
|
160
|
-
if not result:
|
167
|
+
if XML_DIFF_PRESENT and not result:
|
161
168
|
debug += str(
|
162
169
|
xmldiff.main.diff_texts(tostring(xml), tostring(stanza.xml))
|
163
170
|
)
|