slidge 0.2.0b1__py3-none-any.whl → 0.2.2__py3-none-any.whl

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/__version__.py CHANGED
@@ -2,4 +2,4 @@ from slidge.util.util import get_version # noqa: F401
2
2
 
3
3
  # this is modified before publish, but if someone cloned from the repo,
4
4
  # it can help
5
- __version__ = "0.2.0beta1"
5
+ __version__ = "0.2.2"
slidge/command/base.py CHANGED
@@ -245,7 +245,7 @@ class FormField:
245
245
  self.type = "text-private"
246
246
 
247
247
  def __acceptable_options(self) -> list[str]:
248
- if not self.options:
248
+ if self.options is None:
249
249
  raise RuntimeError
250
250
  return [x["value"] for x in self.options]
251
251
 
@@ -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 a single space as a separator"
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
- form_values[f.var] = f.validate(ans.split(" "))
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(
@@ -75,7 +75,8 @@ class Register(Command):
75
75
  self.xmpp.event("user_register", Iq(sfrom=ifrom.bare))
76
76
  return self.SUCCESS_MESSAGE
77
77
 
78
- async def run(self, _session, _ifrom, *_):
78
+ async def run(self, _session, ifrom: JID, *_):
79
+ self.xmpp.raise_if_not_allowed_jid(ifrom)
79
80
  return Form(
80
81
  title=f"Registration to '{self.xmpp.COMPONENT_NAME}'",
81
82
  instructions=self.xmpp.REGISTRATION_INSTRUCTIONS,
@@ -97,7 +98,7 @@ class Register(Command):
97
98
  raise
98
99
 
99
100
  user = GatewayUser(
100
- jid=ifrom.bare,
101
+ jid=JID(ifrom.bare),
101
102
  legacy_module_data=form_values if data is None else data,
102
103
  )
103
104
 
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 "OK"
295
+ return "You are not registered anymore. Bye!"
296
296
 
297
297
 
298
298
  class LeaveGroup(Command):
slidge/contact/contact.py CHANGED
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Generic, Iterable, Optional, Self, Union
6
6
  from xml.etree import ElementTree as ET
7
7
 
8
8
  from slixmpp import JID, Message, Presence
9
- from slixmpp.exceptions import IqError
9
+ from slixmpp.exceptions import IqError, IqTimeout
10
10
  from slixmpp.plugins.xep_0292.stanza import VCard4
11
11
  from slixmpp.types import MessageTypes
12
12
 
@@ -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.readthedocs.io/en/latest/admin/xmpp_server.html for"
457
+ " to https://slidge.im/core/admin/privilege.html for"
458
458
  " more info."
459
459
  )
460
460
  if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
@@ -463,7 +463,7 @@ class LegacyContact(
463
463
  "slidge is not allowed to manage your roster."
464
464
  )
465
465
  return
466
- except IqError as e:
466
+ except (IqError, IqTimeout) as e:
467
467
  self.log.warning("Could not add to roster", exc_info=e)
468
468
  else:
469
469
  # we only broadcast pubsub events for contacts added to the roster
slidge/contact/roster.py CHANGED
@@ -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, XMPPError
7
+ from slixmpp.exceptions import IqError, IqTimeout, XMPPError
8
8
  from slixmpp.jid import JID_UNESCAPE_TRANSFORMATIONS, _unescape_node
9
9
 
10
10
  from ..core.mixins.lock import NamedLockMixin
@@ -210,7 +210,7 @@ class LegacyRoster(
210
210
  self.session.user_jid.bare
211
211
  )
212
212
  user_roster = iq["roster"]["items"]
213
- except (PermissionError, IqError):
213
+ except (PermissionError, IqError, IqTimeout):
214
214
  user_roster = None
215
215
 
216
216
  with self.__store.session() as orm:
@@ -232,7 +232,7 @@ class LegacyRoster(
232
232
  self.session.user_jid.bare,
233
233
  item,
234
234
  )
235
- except (PermissionError, IqError) as e:
235
+ except (PermissionError, IqError, IqTimeout) as e:
236
236
  warnings.warn(f"Could not add to roster: {e}")
237
237
  else:
238
238
  contact._added_to_roster = True
@@ -154,14 +154,13 @@ class PresenceHandlerMixin(DispatcherMixin):
154
154
  # when setting a status message, or going away, etc.
155
155
  return
156
156
 
157
- # We can't use XMPPError here because from must be room@slidge/VALID-USER-NICK
157
+ # We can't use XMPPError here because XMPPError does not have a way to
158
+ # add the <x xmlns="http://jabber.org/protocol/muc" /> element
158
159
 
159
- error_from = JID(muc.jid)
160
- error_from.resource = muc.user_nick
161
160
  error_stanza = p.error()
162
161
  error_stanza.set_to(p.get_from())
163
- error_stanza.set_from(error_from)
164
- error_stanza.enable("muc_join")
162
+ error_stanza.set_from(pto)
163
+ error_stanza.enable("muc_join") # <x xmlns="http://jabber.org/protocol/muc" />
165
164
  error_stanza.enable("error")
166
165
  error_stanza["error"]["type"] = "cancel"
167
166
  error_stanza["error"]["by"] = muc.jid
@@ -2,7 +2,7 @@ import logging
2
2
  from typing import TYPE_CHECKING
3
3
 
4
4
  from slixmpp import Message
5
- from slixmpp.exceptions import IqError
5
+ from slixmpp.exceptions import IqError, IqTimeout
6
6
  from slixmpp.plugins.xep_0084.stanza import Info
7
7
 
8
8
  from ..session import BaseSession
@@ -59,7 +59,7 @@ class SessionDispatcher(
59
59
  iq = await self.xmpp.plugin["xep_0084"].retrieve_avatar(
60
60
  session.user_jid, hash_, ifrom=self.xmpp.boundjid.bare
61
61
  )
62
- except IqError as e:
62
+ except (IqError, IqTimeout) as e:
63
63
  session.log.warning("Could not fetch the user's avatar: %s", e)
64
64
  return
65
65
  bytes_ = iq["pubsub"]["items"]["item"]["avatar_data"]["value"]
slidge/core/gateway.py CHANGED
@@ -429,7 +429,7 @@ class BaseGateway(
429
429
  try:
430
430
  await self["xep_0100"].add_component_to_roster(user.jid)
431
431
  await self.__add_component_to_mds_whitelist(user.jid)
432
- except IqError as e:
432
+ except (IqError, IqTimeout) as e:
433
433
  # TODO: remove the user when this happens? or at least
434
434
  # this can happen when the user has unsubscribed from the XMPP server
435
435
  log.warning(
@@ -464,7 +464,7 @@ class BaseGateway(
464
464
  "create the MDS node of %s",
465
465
  user_jid,
466
466
  )
467
- except IqError as e:
467
+ except (IqError, IqTimeout) as e:
468
468
  # conflict this means the node already exists, we can ignore that
469
469
  if e.condition != "conflict":
470
470
  log.exception(
@@ -548,7 +548,7 @@ class BaseGateway(
548
548
  self.xmpp.plugin["xep_0084"].stanza.MetaData.namespace,
549
549
  ifrom=self.boundjid.bare,
550
550
  )
551
- except IqError:
551
+ except (IqError, IqTimeout):
552
552
  self.xmpp.store.users.set_avatar_hash(session.user_pk, None)
553
553
  return
554
554
  await self.__dispatcher.on_avatar_metadata_info(
@@ -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
 
@@ -19,7 +19,7 @@ from xml.etree import ElementTree as ET
19
19
  import thumbhash
20
20
  from PIL import Image, ImageOps
21
21
  from slixmpp import JID, Message
22
- from slixmpp.exceptions import IqError
22
+ from slixmpp.exceptions import IqError, IqTimeout
23
23
  from slixmpp.plugins.xep_0363 import FileUploadError
24
24
  from slixmpp.plugins.xep_0447.stanza import StatelessFileSharing
25
25
 
@@ -65,7 +65,7 @@ class AttachmentMixin(TextMessageMixin):
65
65
  ifrom=config.UPLOAD_REQUESTER or self.xmpp.boundjid,
66
66
  domain=JID(domain),
67
67
  )
68
- except (FileUploadError, IqError) as e:
68
+ except (FileUploadError, IqError, IqTimeout) as e:
69
69
  warnings.warn(f"Something is wrong with the upload service: {e!r}")
70
70
  return None
71
71
  finally:
@@ -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=reply_to,
390
+ reply_to=reply_to_for_attachment,
380
391
  carbon=carbon,
381
392
  mto=mto,
382
393
  thread=thread,
@@ -172,7 +172,7 @@ class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
172
172
  warnings.warn(
173
173
  "Slidge does not have privileges to send message on behalf of"
174
174
  " user.Refer to"
175
- " https://slidge.readthedocs.io/en/latest/admin/xmpp_server.html"
175
+ " https://slidge.im/core/admin/privilege.html"
176
176
  " for more info."
177
177
  )
178
178
 
slidge/db/models.py CHANGED
@@ -235,11 +235,17 @@ class Room(Base):
235
235
  updated: Mapped[bool] = mapped_column(default=False)
236
236
 
237
237
  participants: Mapped[list["Participant"]] = relationship(
238
- back_populates="room", primaryjoin="Participant.room_id == Room.id"
238
+ back_populates="room",
239
+ primaryjoin="Participant.room_id == Room.id",
240
+ cascade="all, delete-orphan",
239
241
  )
240
242
 
241
243
  avatar_legacy_id: Mapped[Optional[str]] = mapped_column(nullable=True)
242
244
 
245
+ archive: Mapped[list["ArchivedMessage"]] = relationship(
246
+ cascade="all, delete-orphan"
247
+ )
248
+
243
249
 
244
250
  class ArchivedMessage(Base):
245
251
  """
slidge/group/room.py CHANGED
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, AsyncIterator, Generic, Optional, Self, Union
9
9
  from uuid import uuid4
10
10
 
11
11
  from slixmpp import JID, Iq, Message, Presence
12
- from slixmpp.exceptions import IqError, XMPPError
12
+ from slixmpp.exceptions import IqError, IqTimeout, XMPPError
13
13
  from slixmpp.jid import _unescape_node
14
14
  from slixmpp.plugins.xep_0004 import Form
15
15
  from slixmpp.plugins.xep_0060.stanza import Item
@@ -1029,7 +1029,7 @@ class LegacyMUC(
1029
1029
  # (slixmpp annoying magic)
1030
1030
  item = ans["pubsub"]["items"]["item"]
1031
1031
  item["id"] = self.jid
1032
- except IqError:
1032
+ except (IqError, IqTimeout):
1033
1033
  item["conference"]["autojoin"] = auto_join
1034
1034
  except PermissionError:
1035
1035
  warnings.warn(
slidge/main.py CHANGED
@@ -112,7 +112,7 @@ def configure():
112
112
 
113
113
  if not (h := config.HOME_DIR).exists():
114
114
  logging.info("Creating directory '%s'", h)
115
- h.mkdir()
115
+ os.makedirs(h)
116
116
 
117
117
  config.UPLOAD_REQUESTER = config.UPLOAD_REQUESTER or config.JID.bare
118
118
 
@@ -1,12 +1,13 @@
1
1
  # This module contains patches for slixmpp; some have pending requests upstream
2
2
  # and should be removed on the next slixmpp release.
3
- import logging
4
- from collections import defaultdict
3
+
4
+ # ruff: noqa: F401
5
5
 
6
6
  import slixmpp.plugins
7
- from slixmpp import Message
7
+ from slixmpp import Iq, Message
8
+ from slixmpp.exceptions import XMPPError
8
9
  from slixmpp.plugins.xep_0050 import XEP_0050, Command
9
- from slixmpp.plugins.xep_0356.privilege import _VALID_ACCESSES, XEP_0356
10
+ from slixmpp.plugins.xep_0231 import XEP_0231
10
11
  from slixmpp.xmlstream import StanzaBase
11
12
 
12
13
  from . import ( # xep_0356,
@@ -23,36 +24,33 @@ from . import ( # xep_0356,
23
24
  xep_0490,
24
25
  )
25
26
 
26
- # ruff: noqa: F401
27
27
 
28
+ async def _handle_bob_iq(self, iq: Iq):
29
+ cid = iq["bob"]["cid"]
28
30
 
29
- # TODO: Remove me once https://codeberg.org/poezio/slixmpp/pulls/3541 makes it
30
- # to a slixmpp release
31
- def _handle_privilege(self, msg: StanzaBase):
32
- """
33
- Called when the XMPP server advertise the component's privileges.
31
+ if iq["type"] == "result":
32
+ await self.api["set_bob"](iq["from"], None, iq["to"], args=iq["bob"])
33
+ self.xmpp.event("bob", iq)
34
+ elif iq["type"] == "get":
35
+ data = await self.api["get_bob"](iq["to"], None, iq["from"], args=cid)
34
36
 
35
- Stores the privileges in this instance's granted_privileges attribute (a dict)
36
- and raises the privileges_advertised event
37
- """
38
- permissions = self.granted_privileges[msg.get_from()]
39
- for perm in msg["privilege"]["perms"]:
40
- access = perm["access"]
41
- if access == "iq":
42
- if not perm.get_plugin("namespace", check=True):
43
- permissions.iq = defaultdict(lambda: perm["type"])
44
- else:
45
- for ns in perm["namespaces"]:
46
- permissions.iq[ns["ns"]] = ns["type"]
47
- elif access in _VALID_ACCESSES:
48
- setattr(permissions, access, perm["type"])
49
- else:
50
- log.warning("Received an invalid privileged access: %s", access)
51
- log.debug("Privileges: %s", self.granted_privileges)
52
- self.xmpp.event("privileges_advertised")
53
-
54
-
55
- XEP_0356._handle_privilege = _handle_privilege
37
+ if data is None:
38
+ raise XMPPError(
39
+ "item-not-found",
40
+ f"Bits of binary '{cid}' is not available.",
41
+ )
42
+
43
+ if isinstance(data, Iq):
44
+ data["id"] = iq["id"]
45
+ data.send()
46
+ return
47
+
48
+ iq = iq.reply()
49
+ iq.append(data)
50
+ iq.send()
51
+
52
+
53
+ XEP_0231._handle_bob_iq = _handle_bob_iq
56
54
 
57
55
 
58
56
  def session_bind(self, jid):
@@ -98,4 +96,3 @@ slixmpp.plugins.PLUGINS.extend(
98
96
 
99
97
 
100
98
  Message.reply = reply # type: ignore
101
- log = logging.getLogger(__name__)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slidge
3
- Version: 0.2.0b1
3
+ Version: 0.2.2
4
4
  Summary: XMPP bridging framework
5
5
  Home-page: https://sr.ht/~nicoco/slidge/
6
6
  License: AGPL-3.0-or-later
@@ -1,17 +1,17 @@
1
1
  slidge/__init__.py,sha256=S0tUjqpZlzsr8G4Y_1Xt-KCYB07qaknTB0OwHU8k29U,1587
2
2
  slidge/__main__.py,sha256=ydjUklOoavS4YlGfjRX_8BQN2DaSbaXPMi47RkOgcFI,37
3
- slidge/__version__.py,sha256=o9z5MY6bh2r2Gr5POdoOH_xk8Y3xIorqS2ZH6xZtwD4,169
3
+ slidge/__version__.py,sha256=7B4XHb2FWMm2Pq-Bo548FLUn87ezWnj1aoWxA4jTkZs,164
4
4
  slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
5
5
  slidge/command/adhoc.py,sha256=-AO4h1N6owSuuqZon5tDL29O6qmEeAd1pcPjGCkzKRs,10065
6
6
  slidge/command/admin.py,sha256=TYrzgCIhjcTIwl1IUaFlUd3D98SPyao10gB20zo8b3Q,6187
7
- slidge/command/base.py,sha256=S_bKUJB0fnKs58PvjgFf15_6cw-8k2bMeSECTmFxQGQ,13155
7
+ slidge/command/base.py,sha256=S-4WnxDuGE3sQTca5L6DjHVBsHqpNuf6zvXffYoP46c,13159
8
8
  slidge/command/categories.py,sha256=vF0KGDV9sEn8TNkcMoDRw-u3gEyNHSXghOU2JRHQtKs,351
9
- slidge/command/chat_command.py,sha256=8_1mqXNLlcwzozbNhZAAYwxavG09rNR_o9G3TwY-lO8,10941
10
- slidge/command/register.py,sha256=fzPcGUoJtainnDOiC13gWV-uYLuJcsmdKGJ-jXT1qIo,6697
11
- slidge/command/user.py,sha256=0pt9k41npv7MRI_0vauuR1JPb7Gf7UE2lOQeL2XNd7U,12065
9
+ slidge/command/chat_command.py,sha256=z-4qp03rK7kCh3_kEozDViwkDg_hVjHvRCiYYJxedBQ,11153
10
+ slidge/command/register.py,sha256=Zlh5PufPE8EeHLNrFgn3adSPsq-erMpW8uOVYRqFOy8,6756
11
+ slidge/command/user.py,sha256=aksfkRUK7xj9n0XM-IfUSS5LrTp0qIHt5K2UkBBT1UE,12099
12
12
  slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
13
- slidge/contact/contact.py,sha256=kKtJ9NPLS9DPVyyahx_K-Mtp5k5UQdQJZavC1XCmWlc,23104
14
- slidge/contact/roster.py,sha256=-Ei0f0cXX1LFpY29u4Ik68ikno3m2WRA5n5l8Nbjd_E,10267
13
+ slidge/contact/contact.py,sha256=fFWnjgf6HKi782htDyDNS_YVx_baHT24oqjBIruuRRQ,23109
14
+ slidge/contact/roster.py,sha256=x3speGdHbZ-VTLoQLQW4s53rBeBvW87W8ZibCCZSLDA,10300
15
15
  slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
16
16
  slidge/core/config.py,sha256=WP3-ScXqdAhJBX7IRB5pBi_tAV_vE6G5W3Z-LGGULQw,7691
17
17
  slidge/core/dispatcher/__init__.py,sha256=1EXcjXietUKlxEqdrCWCV3xZ3q_DSsjHoqWrPMbtYao,84
@@ -27,21 +27,21 @@ slidge/core/dispatcher/muc/mam.py,sha256=1ROVP4ZPEVEH-HR5qRV4YwHz-V15uu5gyhv1Zww
27
27
  slidge/core/dispatcher/muc/misc.py,sha256=bHBjMC-Pu3jR5hAPGMzXf-C05UbACIwg38YbJUxHIxk,4068
28
28
  slidge/core/dispatcher/muc/owner.py,sha256=1a6YV7b_mmi1jC6q1ko8weeL8imQA-s-hYGPLIHd10I,3308
29
29
  slidge/core/dispatcher/muc/ping.py,sha256=lb1VQPhiUPZ19KhbofRXMVCcY6wwQ2w-asnqtANaAwA,1660
30
- slidge/core/dispatcher/presence.py,sha256=ZxAmC34yxKxbk_-h6g_S8pTssL7ovULm3q2ishpYaB4,6393
30
+ slidge/core/dispatcher/presence.py,sha256=062I98OR2-iJOwU_UT2DHMxK4YlEo6Sbot282ab_-zo,6419
31
31
  slidge/core/dispatcher/registration.py,sha256=Xmbw9NF3LUppCOa3XzreopdKDitZnwl_5HE-kds74n8,3155
32
32
  slidge/core/dispatcher/search.py,sha256=9cGj0wwvyYlP_Yk440Y12sgo4Y1p-JWUDSJP5Zxch0M,3296
33
- slidge/core/dispatcher/session_dispatcher.py,sha256=_njTftgpUKKMP-hgAo99Hu0YrIa6E9OTzSYdiMW000w,2844
33
+ slidge/core/dispatcher/session_dispatcher.py,sha256=vNaOJpHKGTzIyQJX457IvhbooKFN5JR3HA7XW0AArFI,2868
34
34
  slidge/core/dispatcher/util.py,sha256=YtXyVxM3orE7aYWs-GbJumtLTI63OpaQY_t4FMTjoZo,5754
35
35
  slidge/core/dispatcher/vcard.py,sha256=Rmx-wCz6Lps0mXCO48HppNQlS3GOgMuzuw9hZYBdlVU,5130
36
- slidge/core/gateway.py,sha256=NhIgxZKPnOpwsx50OKgyZyk9nfU8ZlUSMddwIDIhFcw,36351
36
+ slidge/core/gateway.py,sha256=m7XN4ACd_txLl4zoAJNJjKT0BFJu6yUfJmhVfUkV7XM,36512
37
37
  slidge/core/mixins/__init__.py,sha256=muReAzgvENgMvlfm0Fpe6BQFfm2EMjoDe9ZhGgo6Vig,627
38
- slidge/core/mixins/attachment.py,sha256=qHtv2I1buTmPO1jwRIpq2rixq5XTAljeWYj2eMWSw2k,19623
38
+ slidge/core/mixins/attachment.py,sha256=LLZ_BFJfYIFtmzX4N2rhBARppyHz5AMLGkspMixkxmg,20128
39
39
  slidge/core/mixins/avatar.py,sha256=kGIIZzLSNuxF9bIvt5Bv03_uT_pU5QV1kS7cRu6-GUA,7874
40
40
  slidge/core/mixins/base.py,sha256=MOd-pas38_52VawQVlxWtBtmTKC6My9G0ZaCeQxOJbs,748
41
41
  slidge/core/mixins/db.py,sha256=5Qpegd7D8e5TLXLLINYcf_DuVdN-7wNmsfztUuFYPcU,442
42
42
  slidge/core/mixins/disco.py,sha256=jk3Z1B6zTuisHv8VKNRJodIo0ee5btYHh2ZrlflPj_Q,3670
43
43
  slidge/core/mixins/lock.py,sha256=Vf1rrkbyNbSprr38WGfZiMgTB7AdbqH8ppFHY8N2yXE,975
44
- slidge/core/mixins/message.py,sha256=FB3VoaT81xUNVnaBMSwNJoHfrVv4Iv2678yDQH-23Rw,7551
44
+ slidge/core/mixins/message.py,sha256=z_uyWkQXXya4yjpPzFmbyTQMIBM1SpUJfcIuysC8NFY,7532
45
45
  slidge/core/mixins/message_maker.py,sha256=TcCutHi0sIwL6beJNkN7XyR0aDIbA0xZyxd2Gc9ulG4,6022
46
46
  slidge/core/mixins/message_text.py,sha256=pCY4tezEuwB2ZuUyUi72i4v9AJkxp_SWF1jrFsn94Ns,8096
47
47
  slidge/core/mixins/presence.py,sha256=yywo6KAw8C7GaZSMrSMuioNfhW08MrnobHt8XbHd0q8,7891
@@ -72,17 +72,17 @@ slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py,sha256=jjQmlRv6nqd
72
72
  slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py,sha256=8Ga3VFgKrzMs_-B8OPtfP-0rey_MFaDg-QGtSbaft3o,640
73
73
  slidge/db/avatar.py,sha256=FfRt2Vu11ZKD9F3x1_drawvUd-TDE3mp7SE3BZ9hOOg,6467
74
74
  slidge/db/meta.py,sha256=v1Jf-npZ28QwdGpsLQWLBHEbEP3-jnPrygRg05tJ_Iw,1831
75
- slidge/db/models.py,sha256=ZbnoUK2yajUJXzyCAWlkTQtkuJAaH1gc9G0ilRpfADg,13812
75
+ slidge/db/models.py,sha256=0NUJfa3lPKHhwV2zE4p7QVYCVs3yn9egFg2u9mssk5c,13964
76
76
  slidge/db/store.py,sha256=KDQ0rp7h6FHgONTYBvucytE7n6Fhsgxgo0pgX18dsTA,46696
77
77
  slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
78
78
  slidge/group/archive.py,sha256=xGPkdSk8-BT6t6lNVo1FEwiFVAttoxCma8Tsyk5r8Kg,5279
79
79
  slidge/group/bookmarks.py,sha256=AvFL34bEX6n3OP1Np309T5hrLK9GnjkjdyLJ3uiLZyc,6616
80
80
  slidge/group/participant.py,sha256=Wtq03Ix55AxlK4pvYVIalLwmKklJiIAsZdeLADJNJgU,17138
81
- slidge/group/room.py,sha256=IizSwUBoKLvcvLpDseHIW_2KAky38uWsSv-poJuCAF0,46019
82
- slidge/main.py,sha256=8oND7xpR3eLw7b62fT61UhYlmNp_9gv3tNz2N3xR7-c,6232
81
+ slidge/group/room.py,sha256=kPy-5bWT8215I1MPJnCCPcaDfSRMiqXx6Fta9BRpLVk,46043
82
+ slidge/main.py,sha256=30cxsolnw-CjCp94jhSjKotCem9rZHCQBpGMP5Ttoos,6237
83
83
  slidge/migration.py,sha256=4BJmPIRB56_WIhRTqBFIIBXuvnhhBjjOMl4CE7jY6oc,1541
84
84
  slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
- slidge/slixfix/__init__.py,sha256=7GevigEt68hwgwHqXcsFogN5jRXRHPeqR6kwODCH4hc,3055
85
+ slidge/slixfix/__init__.py,sha256=A1481U6RCfcJUvKF_Lkek5VI5vKbI0cN12KgQ6rk8GE,2576
86
86
  slidge/slixfix/delivery_receipt.py,sha256=3bWdZH3-X3CZJXmnI_TpjkTUUK-EY4Ktm78lW0-40fc,1366
87
87
  slidge/slixfix/link_preview/__init__.py,sha256=TDPTSEH5FQxgGpQpQIde-D72AHg-6YVWG-tOj4KpKmU,290
88
88
  slidge/slixfix/link_preview/link_preview.py,sha256=9PgdfnoyVMHnXS0w5OFp0wz3ku96Ck-HtRXbVUlDi1U,448
@@ -124,8 +124,8 @@ slidge/util/db.py,sha256=4LxZj8oBYgiSnyBUnF_ALjr0TblkfNQq_p28sCfkHMY,242
124
124
  slidge/util/test.py,sha256=xnGXK0wvua49ncQm4linIfH24Ux6oCkm5A71k2V80zI,14007
125
125
  slidge/util/types.py,sha256=R_xfS5mRL0XUJIoDpnaAkZlTOoLPerduXBFftaVwIAI,5489
126
126
  slidge/util/util.py,sha256=An4BRIHktZGXnu4kCwaKYaSye_PlyuxEm_4SC9YvPhc,9594
127
- slidge-0.2.0b1.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
128
- slidge-0.2.0b1.dist-info/METADATA,sha256=PnfXeM1xUbngKwoPBAuBeiIJ70jxdX7rUcnr2Lq2f0w,5005
129
- slidge-0.2.0b1.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
130
- slidge-0.2.0b1.dist-info/entry_points.txt,sha256=btz6mbzx1X6fjFWAS_Bo5qNi8PtxUsDgunt-6r4JDHw,43
131
- slidge-0.2.0b1.dist-info/RECORD,,
127
+ slidge-0.2.2.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
128
+ slidge-0.2.2.dist-info/METADATA,sha256=RtbebnKhLTIHGQxNMCKlDIL0xGE37uiDZoAswMjRA6k,5003
129
+ slidge-0.2.2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
130
+ slidge-0.2.2.dist-info/entry_points.txt,sha256=btz6mbzx1X6fjFWAS_Bo5qNi8PtxUsDgunt-6r4JDHw,43
131
+ slidge-0.2.2.dist-info/RECORD,,