slidge 0.3.0b1__py3-none-any.whl → 0.3.0b2__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/contact/roster.py CHANGED
@@ -95,6 +95,8 @@ class LegacyRoster(
95
95
  contact_jid = JID(contact_jid.bare)
96
96
  async with self.lock(("username", username)):
97
97
  legacy_id = await self.jid_username_to_legacy_id(username)
98
+ if legacy_id == self.user_legacy_id:
99
+ raise ContactIsUser
98
100
  if self.get_lock(("legacy_id", legacy_id)):
99
101
  self.log.debug("Already updating %s via by_legacy_id()", contact_jid)
100
102
  return await self.by_legacy_id(legacy_id)
@@ -415,7 +415,9 @@ class MessageContentMixin(DispatcherMixin):
415
415
  with self.xmpp.store.session() as orm:
416
416
  sticker = self.xmpp.store.bob.get_sticker(orm, cid)
417
417
  if sticker is None:
418
- await self.xmpp.plugin["xep_0231"].get_bob(from_, cid)
418
+ await self.xmpp.plugin["xep_0231"].get_bob(
419
+ from_, cid, ifrom=self.xmpp.boundjid
420
+ )
419
421
  with self.xmpp.store.session() as orm:
420
422
  sticker = self.xmpp.store.bob.get_sticker(orm, cid)
421
423
  assert sticker is not None
@@ -3,6 +3,7 @@ import logging
3
3
  from slixmpp import JID, Presence
4
4
  from slixmpp.exceptions import XMPPError
5
5
 
6
+ from ...contact.roster import ContactIsUser
6
7
  from ...util.util import merge_resources
7
8
  from ..session import BaseSession
8
9
  from .util import DispatcherMixin, exceptions_to_xmpp_errors
@@ -142,6 +143,10 @@ class PresenceHandlerMixin(DispatcherMixin):
142
143
  contact = await session.contacts.by_jid(pto)
143
144
  except XMPPError:
144
145
  contact = None
146
+ except ContactIsUser:
147
+ raise XMPPError(
148
+ "bad-request", "Actions with yourself are not supported."
149
+ )
145
150
  if contact is not None:
146
151
  await self.xmpp.pubsub.on_presence_available(p, contact)
147
152
  return
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Optional
4
4
 
5
5
  from PIL import UnidentifiedImageError
6
6
  from slixmpp import JID
7
- from sqlalchemy.exc import IntegrityError
8
7
  from sqlalchemy.orm.exc import DetachedInstanceError
9
8
 
10
9
  from ...db.avatar import CachedAvatar, avatar_cache
@@ -124,25 +123,14 @@ class AvatarMixin(UpdateInfoMixin):
124
123
  avatar.path.unlink()
125
124
 
126
125
  stored_avatar = None if cached_avatar is None else cached_avatar.stored
127
- self.stored.avatar = stored_avatar
128
-
129
- try:
130
- self.commit(merge=True)
131
- except IntegrityError as e:
132
- with self.xmpp.store.session(expire_on_commit=False) as orm:
133
- if orm.object_session(self.stored):
134
- self.log.debug(
135
- "Hit integrity error, attempting to fix by refreshing participants"
136
- )
137
- orm.refresh(self.stored, ["participants"])
138
- else:
139
- self.log.debug(
140
- "Hit integrity error, attempting to fix by merging contact.stored"
141
- )
126
+ if not self._updating_info:
127
+ with self.xmpp.store.session() as orm:
128
+ with orm.no_autoflush:
142
129
  self.stored = orm.merge(self.stored)
143
- self.stored.avatar = stored_avatar
144
- orm.add(self.stored)
145
- orm.commit()
130
+ orm.refresh(self.stored)
131
+
132
+ self.stored.avatar = stored_avatar
133
+ self.commit(merge=True)
146
134
 
147
135
  self._post_avatar_update(cached_avatar)
148
136
 
slidge/core/session.py CHANGED
@@ -133,8 +133,8 @@ class BaseSession(
133
133
  self.log.debug("Removing fut %s", fut)
134
134
  self.__tasks.remove(fut)
135
135
 
136
- def create_task(self, coro) -> asyncio.Task:
137
- task = self.xmpp.loop.create_task(coro)
136
+ def create_task(self, coro, name: str | None = None) -> asyncio.Task:
137
+ task = self.xmpp.loop.create_task(coro, name=name)
138
138
  self.__tasks.add(task)
139
139
  self.log.debug("Creating task %s", task)
140
140
  task.add_done_callback(lambda _: self.__remove_task(task))
slidge/group/room.py CHANGED
@@ -3,6 +3,8 @@ import logging
3
3
  import re
4
4
  import string
5
5
  import warnings
6
+ from asyncio import Lock
7
+ from contextlib import asynccontextmanager
6
8
  from copy import copy
7
9
  from datetime import datetime, timedelta, timezone
8
10
  from typing import TYPE_CHECKING, AsyncIterator, Generic, Optional, Type, Union
@@ -18,7 +20,6 @@ from slixmpp.plugins.xep_0469.stanza import NS as PINNING_NS
18
20
  from slixmpp.plugins.xep_0492.stanza import NS as NOTIFY_NS
19
21
  from slixmpp.plugins.xep_0492.stanza import WhenLiteral
20
22
  from slixmpp.xmlstream import ET
21
- from sqlalchemy.exc import InvalidRequestError
22
23
  from sqlalchemy.orm import Session as OrmSession
23
24
 
24
25
  from ..contact.contact import LegacyContact
@@ -28,7 +29,6 @@ from ..core.mixins.disco import ChatterDiscoMixin
28
29
  from ..core.mixins.recipient import ReactionRecipientMixin, ThreadRecipientMixin
29
30
  from ..db.models import Participant, Room
30
31
  from ..util.jid_escaping import unescape_node
31
- from ..util.lock import NamedLockMixin
32
32
  from ..util.types import (
33
33
  HoleBound,
34
34
  LegacyGroupIdType,
@@ -56,7 +56,6 @@ class LegacyMUC(
56
56
  LegacyGroupIdType, LegacyMessageType, LegacyParticipantType, LegacyUserIdType
57
57
  ],
58
58
  AvatarMixin,
59
- NamedLockMixin,
60
59
  ChatterDiscoMixin,
61
60
  ReactionRecipientMixin,
62
61
  ThreadRecipientMixin,
@@ -242,10 +241,22 @@ class LegacyMUC(
242
241
  )
243
242
  self.commit()
244
243
 
244
+ @asynccontextmanager
245
+ async def lock(self, id_: str) -> AsyncIterator[None]:
246
+ async with self.session.lock((self.legacy_id, id_)):
247
+ yield
248
+
249
+ def get_lock(self, id_: str) -> Lock | None:
250
+ return self.session.get_lock((self.legacy_id, id_))
251
+
245
252
  async def __fill_participants(self) -> None:
246
- if self.participants_filled:
247
- return
248
253
  async with self.lock("fill participants"):
254
+ with self.xmpp.store.session(expire_on_commit=False) as orm:
255
+ orm.add(self.stored)
256
+ with orm.no_autoflush:
257
+ orm.refresh(self.stored, ["participants_filled"])
258
+ if self.participants_filled:
259
+ return
249
260
  parts: list[Participant] = []
250
261
  resources = set[str]()
251
262
  # During fill_participants(), self.get_participant*() methods may
@@ -261,17 +272,13 @@ class LegacyMUC(
261
272
  resources.add(participant.stored.resource)
262
273
  with self.xmpp.store.session(expire_on_commit=False) as orm:
263
274
  orm.add(self.stored)
264
- # because self.participants() is async, self.stored may be out of sync at
265
- # this point.
275
+ # because self.fill_participants() is async, self.stored may be stale at
276
+ # this point, and the only thing we want to update is the participant list
277
+ # and the participant_filled attribute.
266
278
  with orm.no_autoflush:
267
279
  orm.refresh(self.stored)
268
- for part in parts:
269
- try:
270
- self.stored.participants.append(part)
271
- except InvalidRequestError:
272
- # the participant was already stored in the DB. `part` may even
273
- # be out-of-sync, so it's fine to just ditch it.
274
- pass
280
+ for part in parts:
281
+ orm.merge(part)
275
282
  self.stored.participants_filled = True
276
283
  orm.commit()
277
284
 
@@ -290,10 +297,14 @@ class LegacyMUC(
290
297
  yield self.participant_from_store(db_participant)
291
298
 
292
299
  async def __fill_history(self) -> None:
293
- if self.stored.history_filled:
294
- self.log.debug("History has already been fetched.")
295
- return
296
300
  async with self.lock("fill history"):
301
+ with self.xmpp.store.session(expire_on_commit=False) as orm:
302
+ orm.add(self.stored)
303
+ with orm.no_autoflush:
304
+ orm.refresh(self.stored, ["history_filled"])
305
+ if self.stored.history_filled:
306
+ self.log.debug("History has already been fetched.")
307
+ return
297
308
  log.debug("Fetching history for %s", self)
298
309
  try:
299
310
  before, after = self.archive.get_hole_bounds()
@@ -767,16 +778,15 @@ class LegacyMUC(
767
778
  """
768
779
  await self.session.contacts.ready
769
780
 
770
- if not self.get_lock("fill participants"):
771
- with self.xmpp.store.session() as orm:
772
- self.stored = orm.merge(self.stored)
773
- stored = (
774
- orm.query(Participant)
775
- .filter_by(contact=c.stored, room=self.stored)
776
- .one_or_none()
777
- )
778
- if stored is not None:
779
- return self.participant_from_store(stored=stored, contact=c)
781
+ with self.xmpp.store.session() as orm:
782
+ self.stored = orm.merge(self.stored)
783
+ stored = (
784
+ orm.query(Participant)
785
+ .filter_by(contact=c.stored, room=self.stored)
786
+ .one_or_none()
787
+ )
788
+ if stored is not None:
789
+ return self.participant_from_store(stored=stored, contact=c)
780
790
 
781
791
  nickname = c.name or unescape_node(c.jid.node)
782
792
 
slidge/main.py CHANGED
@@ -166,10 +166,12 @@ def main(module_name: str | None = None) -> None:
166
166
  f"_{config.LEGACY_MODULE.split('.')[-1].upper()}_"
167
167
  )
168
168
  logging.debug("Env var prefix: %s", ConfigModule.ENV_VAR_PREFIX)
169
- ConfigModule(plugin_config_obj).set_conf(unknown_argv)
170
- else:
171
- if unknown_argv:
172
- raise RuntimeError("Some arguments have not been recognized", unknown_argv)
169
+ _, unknown_argv = ConfigModule(plugin_config_obj).set_conf(unknown_argv)
170
+
171
+ if unknown_argv:
172
+ logging.error(
173
+ f"These config options have not been recognized and ignored: {unknown_argv}"
174
+ )
173
175
 
174
176
  migrate()
175
177
 
slidge/util/conf.py CHANGED
@@ -159,7 +159,10 @@ class ConfigModule:
159
159
  upper = _argv_to_option_name(a)
160
160
  opt = options_long.get(upper)
161
161
  if opt and opt.type is bool:
162
- if _argv_to_option_name(aa) not in options_long:
162
+ if (
163
+ not aa.startswith("-")
164
+ and _argv_to_option_name(aa) not in options_long
165
+ ):
163
166
  log.debug("Removing %s from argv", aa)
164
167
  skip_next = True
165
168
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slidge
3
- Version: 0.3.0b1
3
+ Version: 0.3.0b2
4
4
  Summary: XMPP bridging framework
5
5
  Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  slidge/__init__.py,sha256=OWGOMz8wl6I6XNUT9ipE9IFD-OinS8zQGGn4U_z3IWw,1835
2
2
  slidge/__main__.py,sha256=ydjUklOoavS4YlGfjRX_8BQN2DaSbaXPMi47RkOgcFI,37
3
- slidge/main.py,sha256=Q2memNl050JJhUk-ZKHV2Q2lVpdMtoyLKupKswq-swM,7070
3
+ slidge/main.py,sha256=bUdAau6TorsPpDRBPfzvUolHlXF5K-BY9aJdSmNUcyw,7109
4
4
  slidge/migration.py,sha256=Y_PJ9ahHwcgwP1gnGByIiUJSxTu2DYFpmNiPdOpVgoQ,1545
5
5
  slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
@@ -13,16 +13,16 @@ slidge/command/register.py,sha256=BduDI31Kx8CbWWEdjybimTA5Wcfhn-Jkt8sSPsySCpo,67
13
13
  slidge/command/user.py,sha256=VS7xuADXXes941OyiJbxC_C8d5hcqm-TSS4Gu82_8PQ,12173
14
14
  slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
15
15
  slidge/contact/contact.py,sha256=AZSpBInijGXn5hP_eJQhdyCOcUnzM62h65ZliyFZWhg,19497
16
- slidge/contact/roster.py,sha256=TAPvaPWUn77CHt8la_BLfQRkZZJhlG-hn2wEQZbGzJ8,9706
16
+ slidge/contact/roster.py,sha256=uZ3iCl8oa7kEpIptUVa9p1k51bSvbuQq1pUGnf_zru8,9791
17
17
  slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
18
18
  slidge/core/config.py,sha256=1HxHQ5BOnYghi8V5KbCQ6sUsNnXzAZAIoFA5PrMqH4E,6060
19
19
  slidge/core/gateway.py,sha256=0nuWlig6K4urNowoEKCVkSvEVH46BhR70A52fH6O4AE,40956
20
20
  slidge/core/pubsub.py,sha256=-YK49tEdz_SLM3O8Y9zvu3p5KYhxgNpqbsD57rOIdNI,12141
21
- slidge/core/session.py,sha256=H6eZqjDYrQu5k26dCYH3GAWg-P2tdYin06aufuIrnWw,29464
21
+ slidge/core/session.py,sha256=Rji81tCEVI5zpKtKpMIuclKvDR0XuHZRki8ivIhtNnQ,29500
22
22
  slidge/core/dispatcher/__init__.py,sha256=1EXcjXietUKlxEqdrCWCV3xZ3q_DSsjHoqWrPMbtYao,84
23
23
  slidge/core/dispatcher/caps.py,sha256=gISaHtFwFDXtkSrSsAkZfPiHQyXfmXg3v_YYU0w9iDg,2254
24
24
  slidge/core/dispatcher/disco.py,sha256=xVPyBFnnkON-JjjM1oydRa-dqnDbwAZER2MGQACRhVk,2309
25
- slidge/core/dispatcher/presence.py,sha256=XrcWGjIHofmAu_8QIOMsF6Wlg4_kyPukp73FPm8BwOg,6721
25
+ slidge/core/dispatcher/presence.py,sha256=rxL2tDlH7a1NxfN_URDNFCHnjG_e-4Ke5UWMh8zXeOo,6928
26
26
  slidge/core/dispatcher/registration.py,sha256=Qa3fYZFJ4NaVz-FsnXorCmMQ9WyO7oZte1Zvro5f74E,3415
27
27
  slidge/core/dispatcher/search.py,sha256=bL5cwMOtsfnX5IH-t60S1PudpeMWZnF4-qksrKDuDyc,3411
28
28
  slidge/core/dispatcher/session_dispatcher.py,sha256=ysgPhns7NgUxhmkgEwRv-yDkSnUIXEdc-FsgqDqQAkE,3466
@@ -31,7 +31,7 @@ slidge/core/dispatcher/vcard.py,sha256=qHZZShq3Iyvgh1FkcAgGhdKXF5m1VUqeb4EWkY0cb
31
31
  slidge/core/dispatcher/message/__init__.py,sha256=gNeZZ0wtCI9JBqMe6tpumwV1TjY0mnPWTJc94uFTN-I,244
32
32
  slidge/core/dispatcher/message/chat_state.py,sha256=RbtM_nlZyvOHusZkDEP0TXA4wMp_N435490eE4wW8U0,2143
33
33
  slidge/core/dispatcher/message/marker.py,sha256=WZyf72_SM6sDGPMEOzhu93o2KbgxSxNF25jwsiM7h2A,2439
34
- slidge/core/dispatcher/message/message.py,sha256=IEXbgaErWk8L-xQhkUXdYlruzk7x84Q1BjltLGjFxXI,16146
34
+ slidge/core/dispatcher/message/message.py,sha256=RK1sX4cBSvPZLiUGYoT-pdCB01ll1761Ryr7Tu0AuBc,16202
35
35
  slidge/core/dispatcher/muc/__init__.py,sha256=60YUr0i8PCZEPyNNTynJueRbbxF5pqzdyVf8z_XFXmM,290
36
36
  slidge/core/dispatcher/muc/admin.py,sha256=1tDZ9hHD6q5SqCjsYOpDimPB3Iyl21YO5RnK1goEGso,3284
37
37
  slidge/core/dispatcher/muc/mam.py,sha256=7vfmMI_mJOIrc9KCbtTibJSowhZTBBFwXWc84Ikpu3I,2994
@@ -40,7 +40,7 @@ slidge/core/dispatcher/muc/owner.py,sha256=dDAxpRaA8H_NJQNIyBNixck2oG4GHZeEQqPhK
40
40
  slidge/core/dispatcher/muc/ping.py,sha256=EgKKS9AvMnW-vINGcoGbtk6NdbN9A7zVaGfT5T7F6YE,1699
41
41
  slidge/core/mixins/__init__.py,sha256=Zea39CCwjJU5XfHwcYPEZ9Sin8z1BZxoV68G2RwC3nE,386
42
42
  slidge/core/mixins/attachment.py,sha256=f_8SZGyEAK00fzpwUWyIocPzdkSl5awPihR6_GCgdDo,21766
43
- slidge/core/mixins/avatar.py,sha256=x-PAbJFoMKZLoScVjIVzFuQvnJ4geXoAQrFHr5G_SOA,6113
43
+ slidge/core/mixins/avatar.py,sha256=0E0mQxdTUcJQrYXlBkYqkNl4bYuga4cIC1s4XA2rED8,5559
44
44
  slidge/core/mixins/base.py,sha256=MOd-pas38_52VawQVlxWtBtmTKC6My9G0ZaCeQxOJbs,748
45
45
  slidge/core/mixins/db.py,sha256=a6idm-FgHWfDK-MJZWy5AkkBlyY8JmwOB8xAFmm0E9g,1934
46
46
  slidge/core/mixins/disco.py,sha256=jk3Z1B6zTuisHv8VKNRJodIo0ee5btYHh2ZrlflPj_Q,3670
@@ -62,7 +62,7 @@ slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
62
62
  slidge/group/archive.py,sha256=DKwyde15-Op2rXuQBvdSmFcAKhUyWuorpEFcRSmDHec,5956
63
63
  slidge/group/bookmarks.py,sha256=UWrUjZMWlDmwKFRuNEqxZSx4cvXFib4AP_l388ApJa8,7086
64
64
  slidge/group/participant.py,sha256=eMwUgbEtxGjWMmIqUfS8uSKlaStitZ3D68M_RixQeso,17676
65
- slidge/group/room.py,sha256=meASJZXRVM39SEzoLNjm0NAx6mLLa8dgA21tK828kik,47939
65
+ slidge/group/room.py,sha256=_KP0jIh9f9k0yDRWCe7BsZBQesfm1lwbHpN9WYRKuzc,48391
66
66
  slidge/slixfix/__init__.py,sha256=LvaYZQYjr4l_45AYYpod1dB3MUaZye18vKF-4H8Bm20,4758
67
67
  slidge/slixfix/delivery_receipt.py,sha256=JmogxsiXYEbTmCM4fvC5wkQs0jBsaJtKl4j_B_18riE,1415
68
68
  slidge/slixfix/roster.py,sha256=DjjHQqCsKsPChUxV7S0Pm4IAgjfrwgm5tcTdJi3N_gY,1670
@@ -81,15 +81,15 @@ slidge/slixfix/xep_0292/__init__.py,sha256=_MvS9wGra6ig3P_dPAVlCPDJkiOFvUWGjaRsH
81
81
  slidge/slixfix/xep_0292/vcard4.py,sha256=I6EXdTQ51nfF5qvKh7WMAluELbFsdtnYHrsV_8PrjK4,366
82
82
  slidge/util/__init__.py,sha256=BELovoTMPcPPGz3D48esBr8A4BRRHXTvavfgnArBgEc,301
83
83
  slidge/util/archive_msg.py,sha256=hGNquu38ouSWSc-kz_oAYPXwjhUVZNSedIpwkrXHSd0,1826
84
- slidge/util/conf.py,sha256=uNDY6GdQyTZEV47ab9fi27wwRb0ZMvbuZ7Hbzfe_NT8,7269
84
+ slidge/util/conf.py,sha256=Wv-xr1fQfz6jDCBpj2e5Nm-igMpdIjsYsVfoY8grJoo,7380
85
85
  slidge/util/jid_escaping.py,sha256=QJ2Yj_j1gTmiO9g2r187iVCu7kia_O5ABhRiLAO2TG4,1073
86
86
  slidge/util/lock.py,sha256=ZnUi3LGiz271-YeYKo9JzxovJCoSwlP9P65pNyHIO9o,1029
87
87
  slidge/util/test.py,sha256=_E6er2BtQlpyzTUmp4u8C9KhBYzbLrmTwSVgxGObKHU,13988
88
88
  slidge/util/types.py,sha256=xJ84ZvaUOU_VVJSjEMysgNSl05k0_O9YKbyW-JUrsMI,5635
89
89
  slidge/util/util.py,sha256=4hihLCl4SsB5S14TT3bP8tDPP_Zg9rYbSfLdLB9-G_Q,9332
90
- slidge-0.3.0b1.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
91
- slidge-0.3.0b1.dist-info/METADATA,sha256=6PmV4nthNFFylMq1FHcXwhSuEgN9mQ9EaeUWuGNNNl4,5056
92
- slidge-0.3.0b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
93
- slidge-0.3.0b1.dist-info/entry_points.txt,sha256=py3_x834fFJ2TEzPd18Wt2DnysdAfuVqJ5zzBrXbAZs,44
94
- slidge-0.3.0b1.dist-info/top_level.txt,sha256=2LRjDYHaGZ5ieCMF8xy58JIiabRMzX-MGMbCZwfE17c,7
95
- slidge-0.3.0b1.dist-info/RECORD,,
90
+ slidge-0.3.0b2.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
91
+ slidge-0.3.0b2.dist-info/METADATA,sha256=_O_tp1b_KiJA94aoQQG0e0Nbg37mt-P7BFJY6Gn0xcg,5056
92
+ slidge-0.3.0b2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
93
+ slidge-0.3.0b2.dist-info/entry_points.txt,sha256=py3_x834fFJ2TEzPd18Wt2DnysdAfuVqJ5zzBrXbAZs,44
94
+ slidge-0.3.0b2.dist-info/top_level.txt,sha256=2LRjDYHaGZ5ieCMF8xy58JIiabRMzX-MGMbCZwfE17c,7
95
+ slidge-0.3.0b2.dist-info/RECORD,,