slidge 0.2.4__py3-none-any.whl → 0.2.5__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 +6 -2
- slidge/contact/contact.py +1 -1
- slidge/core/config.py +12 -1
- slidge/core/gateway.py +12 -2
- slidge/core/mixins/attachment.py +1 -0
- slidge/core/mixins/message.py +1 -1
- slidge/core/pubsub.py +2 -1
- slidge/db/avatar.py +20 -1
- slidge/db/store.py +2 -0
- slidge/group/participant.py +9 -1
- {slidge-0.2.4.dist-info → slidge-0.2.5.dist-info}/METADATA +7 -6
- {slidge-0.2.4.dist-info → slidge-0.2.5.dist-info}/RECORD +16 -16
- {slidge-0.2.4.dist-info → slidge-0.2.5.dist-info}/WHEEL +0 -0
- {slidge-0.2.4.dist-info → slidge-0.2.5.dist-info}/entry_points.txt +0 -0
- {slidge-0.2.4.dist-info → slidge-0.2.5.dist-info}/top_level.txt +0 -0
slidge/__version__.py
CHANGED
slidge/command/base.py
CHANGED
@@ -293,12 +293,16 @@ class FormField:
|
|
293
293
|
return value
|
294
294
|
|
295
295
|
def __validate_list_multi(self, value: list[str]) -> Union[list[str], list[JID]]:
|
296
|
+
# COMPAT: all the "if v" and "if not v" are workarounds for https://codeberg.org/slidge/slidge/issues/43
|
297
|
+
# They should be reverted once the bug is fixed upstream, cf https://soprani.ca/todo/390
|
296
298
|
for v in value:
|
297
299
|
if v not in self.__acceptable_options():
|
300
|
+
if not v:
|
301
|
+
continue
|
298
302
|
raise XMPPError("not-acceptable", f"Not a valid option: '{v}'")
|
299
303
|
if self.type == "list-multi":
|
300
|
-
return value
|
301
|
-
return [JID(v) for v in value]
|
304
|
+
return [v for v in value if v]
|
305
|
+
return [JID(v) for v in value if v]
|
302
306
|
|
303
307
|
def get_xml(self) -> SlixFormField:
|
304
308
|
"""
|
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.im/docs/slidge/main/admin/privilege.html for"
|
458
458
|
" more info."
|
459
459
|
)
|
460
460
|
if config.ROSTER_PUSH_PRESENCE_SUBSCRIPTION_REQUEST_FALLBACK:
|
slidge/core/config.py
CHANGED
@@ -187,7 +187,7 @@ MAM_MAX_DAYS__DOC = "Maximum number of days for group archive retention."
|
|
187
187
|
CORRECTION_EMPTY_BODY_AS_RETRACTION = True
|
188
188
|
CORRECTION_EMPTY_BODY_AS_RETRACTION__DOC = (
|
189
189
|
"Treat last message correction to empty message as a retraction. "
|
190
|
-
"(this is what cheogram
|
190
|
+
"(this is what cheogram does for retraction)"
|
191
191
|
)
|
192
192
|
|
193
193
|
ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH = 200
|
@@ -220,3 +220,14 @@ STRIP_LEADING_EMOJI_ADHOC__DOC = (
|
|
220
220
|
"Strip the leading emoji in ad-hoc command names, if present, in case you "
|
221
221
|
"are a emoji-hater."
|
222
222
|
)
|
223
|
+
|
224
|
+
COMPONENT_NAME: Optional[str] = None
|
225
|
+
COMPONENT_NAME__DOC = (
|
226
|
+
"Overrides the default component name with a custom one. This is seen in service discovery and as the nickname "
|
227
|
+
"of the component in chat windows."
|
228
|
+
)
|
229
|
+
|
230
|
+
WELCOME_MESSAGE: Optional[str] = None
|
231
|
+
WELCOME_MESSAGE__DOC = (
|
232
|
+
"Overrides the default welcome message received by newly registered users."
|
233
|
+
)
|
slidge/core/gateway.py
CHANGED
@@ -254,6 +254,10 @@ class BaseGateway(
|
|
254
254
|
http: aiohttp.ClientSession
|
255
255
|
|
256
256
|
def __init__(self):
|
257
|
+
if config.COMPONENT_NAME:
|
258
|
+
self.COMPONENT_NAME = config.COMPONENT_NAME
|
259
|
+
if config.WELCOME_MESSAGE:
|
260
|
+
self.WELCOME_MESSAGE = config.WELCOME_MESSAGE
|
257
261
|
self.log = log
|
258
262
|
self.datetime_started = datetime.now()
|
259
263
|
self.xmpp = self # ugly hack to work with the BaseSender mixin :/
|
@@ -416,8 +420,14 @@ class BaseGateway(
|
|
416
420
|
await self.plugin["xep_0115"].update_caps(jid=self.boundjid)
|
417
421
|
|
418
422
|
if self.COMPONENT_AVATAR is not None:
|
419
|
-
|
420
|
-
|
423
|
+
try:
|
424
|
+
cached_avatar = await avatar_cache.convert_or_get(self.COMPONENT_AVATAR)
|
425
|
+
except Exception as e:
|
426
|
+
log.exception("Could not set the component avatar.", exc_info=e)
|
427
|
+
cached_avatar = None
|
428
|
+
else:
|
429
|
+
assert cached_avatar is not None
|
430
|
+
self.avatar_pk = cached_avatar.pk
|
421
431
|
else:
|
422
432
|
cached_avatar = None
|
423
433
|
|
slidge/core/mixins/attachment.py
CHANGED
slidge/core/mixins/message.py
CHANGED
@@ -183,7 +183,7 @@ class CarbonMessageMixin(ContentMessageMixin, MarkerMixin):
|
|
183
183
|
warnings.warn(
|
184
184
|
"Slidge does not have privileges to send message on behalf of"
|
185
185
|
" user.Refer to"
|
186
|
-
" https://slidge.
|
186
|
+
" https://slidge.im/docs/slidge/main/admin/privilege.html"
|
187
187
|
" for more info."
|
188
188
|
)
|
189
189
|
|
slidge/core/pubsub.py
CHANGED
@@ -207,7 +207,8 @@ class PubSubComponent(NamedLockMixin, BasePlugin):
|
|
207
207
|
) -> PepAvatar:
|
208
208
|
if stanza.get_to() == self.xmpp.boundjid.bare:
|
209
209
|
item = PepAvatar()
|
210
|
-
|
210
|
+
if hasattr(self.xmpp, "avatar_pk"):
|
211
|
+
item.set_avatar_from_cache(avatar_cache.get_by_pk(self.xmpp.avatar_pk))
|
211
212
|
return item
|
212
213
|
|
213
214
|
if contact is None:
|
slidge/db/avatar.py
CHANGED
@@ -14,6 +14,7 @@ from multidict import CIMultiDictProxy
|
|
14
14
|
from PIL.Image import Image
|
15
15
|
from PIL.Image import open as open_image
|
16
16
|
from sqlalchemy import select
|
17
|
+
from sqlalchemy.orm.exc import DetachedInstanceError
|
17
18
|
|
18
19
|
from slidge.core import config
|
19
20
|
from slidge.db.models import Avatar
|
@@ -102,6 +103,7 @@ class AvatarCache:
|
|
102
103
|
if response.status == HTTPStatus.NOT_MODIFIED:
|
103
104
|
log.debug("Using avatar cache for %s", url)
|
104
105
|
raise NotModified
|
106
|
+
response.raise_for_status()
|
105
107
|
return (
|
106
108
|
open_image(io.BytesIO(await response.read())),
|
107
109
|
response.headers,
|
@@ -141,7 +143,24 @@ class AvatarCache:
|
|
141
143
|
)
|
142
144
|
except NotModified:
|
143
145
|
assert stored is not None
|
144
|
-
|
146
|
+
try:
|
147
|
+
return CachedAvatar.from_store(stored, self.dir)
|
148
|
+
except DetachedInstanceError:
|
149
|
+
# This is an awful hack to prevent errors on startup under certain conditions,
|
150
|
+
# because we basically misused SQLAlchemy pretty bad in slidge.db.store.EngineMixin.session().
|
151
|
+
# cf https://codeberg.org/slidge/slidge/issues/36
|
152
|
+
# and https://docs.sqlalchemy.org/en/20/orm/session_basics.html#session-faq-threadsafe
|
153
|
+
# It may be related to threads as we only have reports of this for slidge-whatsapp and skidge
|
154
|
+
# which are the only implementations that uses threads.
|
155
|
+
# In any case, a proper fix implies a major refactoring in which we spawn and close SQLAlchemy
|
156
|
+
# "ORM Session"s with a reasonable, well-thought lifetime, instead of how we do it now, where we
|
157
|
+
# basically just brute-forced our way into having something usable but with poor performance.
|
158
|
+
# Databases, asyncio, and concurrency in general are hard… :(
|
159
|
+
# Oh, and getting rid of the convoluted mess that this giant method is would also probably
|
160
|
+
# be a good idea.
|
161
|
+
stored = self.store.get_by_url(avatar)
|
162
|
+
assert stored is not None
|
163
|
+
return CachedAvatar.from_store(stored, self.dir)
|
145
164
|
else:
|
146
165
|
img = await self._get_image(avatar)
|
147
166
|
response_headers = None
|
slidge/db/store.py
CHANGED
@@ -58,6 +58,8 @@ class EngineMixin:
|
|
58
58
|
def __init__(self, engine: Engine):
|
59
59
|
self._engine = engine
|
60
60
|
|
61
|
+
# TODO: we should not have a global Session object but instead build Sessions with different parameters
|
62
|
+
# depending on the context (startup, incoming XMPP event, incoming legacy event).
|
61
63
|
@contextmanager
|
62
64
|
def session(self, **session_kwargs) -> Iterator[Session]:
|
63
65
|
global _session
|
slidge/group/participant.py
CHANGED
@@ -70,6 +70,7 @@ class LegacyParticipant(
|
|
70
70
|
is_system=False,
|
71
71
|
role: MucRole = "participant",
|
72
72
|
affiliation: MucAffiliation = "member",
|
73
|
+
resource: str | None = None,
|
73
74
|
):
|
74
75
|
self.session = session = muc.session
|
75
76
|
self.xmpp = session.xmpp
|
@@ -83,7 +84,13 @@ class LegacyParticipant(
|
|
83
84
|
|
84
85
|
self._nickname = nickname
|
85
86
|
|
86
|
-
|
87
|
+
if resource is None:
|
88
|
+
self.__update_jid(nickname)
|
89
|
+
else:
|
90
|
+
self._nickname_no_illegal = resource
|
91
|
+
self.jid = JID(self.muc.jid)
|
92
|
+
self.jid.resource = resource
|
93
|
+
|
87
94
|
log.debug("Instantiation of: %r", self)
|
88
95
|
|
89
96
|
self.contact: Optional["LegacyContact"] = None
|
@@ -510,6 +517,7 @@ class LegacyParticipant(
|
|
510
517
|
stored.nickname,
|
511
518
|
role=stored.role,
|
512
519
|
affiliation=stored.affiliation,
|
520
|
+
resource=stored.resource,
|
513
521
|
)
|
514
522
|
part.pk = stored.id
|
515
523
|
if contact is not None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: slidge
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.5
|
4
4
|
Summary: XMPP bridging framework
|
5
5
|
Author-email: Nicolas Cedilnik <nicoco@nicoco.fr>
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
@@ -669,7 +669,8 @@ Project-URL: Homepage, https://codeberg.org/slidge/
|
|
669
669
|
Project-URL: Issues, https://codeberg.org/slidge/slidge/issues
|
670
670
|
Project-URL: Repository, https://codeberg.org/slidge/slidge/
|
671
671
|
Project-URL: Chat room, https://conference.nicoco.fr:5281/muc_log/slidge/
|
672
|
-
Project-URL: Documentation, https://slidge.
|
672
|
+
Project-URL: Documentation, https://slidge.im/docs/slidge/main
|
673
|
+
Project-URL: changelog, https://codeberg.org/slidge/slidge/releases
|
673
674
|
Keywords: xmpp,gateway,bridge,instant messaging
|
674
675
|
Classifier: Topic :: Internet :: XMPP
|
675
676
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
@@ -693,14 +694,14 @@ Requires-Dist: thumbhash>=0.1.2
|
|
693
694
|
|
694
695
|
|
695
696
|
[![woodpecker CI status](https://ci.codeberg.org/api/badges/14027/status.svg)](https://ci.codeberg.org/repos/14027)
|
696
|
-
[![coverage](https://slidge.
|
697
|
+
[![coverage](https://slidge.im/coverage/main/coverage.svg)](https://slidge.im/coverage/main)
|
697
698
|
|
698
699
|
[![pypi version](https://badge.fury.io/py/slidge.svg)](https://pypi.org/project/slidge/)
|
699
700
|
[![debian unstable version](https://badges.debian.net/badges/debian/unstable/python3-slidge/version.svg)](https://packages.debian.org/unstable/python3-slidge)
|
700
701
|
|
701
702
|
Slidge is an XMPP (puppeteer) gateway library in python.
|
702
703
|
It makes
|
703
|
-
[writing gateways to other chat networks](https://slidge.im/
|
704
|
+
[writing gateways to other chat networks](https://slidge.im/docs/slidge/main/dev/tutorial.html)
|
704
705
|
(*legacy modules*) as frictionless as possible.
|
705
706
|
It supports fancy IM features, such as
|
706
707
|
[(emoji) reactions](https://xmpp.org/extensions/xep-0444.html),
|
@@ -751,7 +752,7 @@ class Session(BaseSession):
|
|
751
752
|
self.legacy_client.send_message(text=text, destination=chat.legacy_id)
|
752
753
|
```
|
753
754
|
|
754
|
-
There's more in [the tutorial](https://slidge.
|
755
|
+
There's more in [the tutorial](https://slidge.im/docs/slidge/main/dev/tutorial.html)!
|
755
756
|
|
756
757
|
Installation
|
757
758
|
------------
|
@@ -766,7 +767,7 @@ bundle.
|
|
766
767
|
Slidge is available on
|
767
768
|
[codeberg](https://codeberg.org/slidge/-/packages) (python packages and containers)
|
768
769
|
and [pypi](https://pypi.org/project/slidge/).
|
769
|
-
Refer to [the docs](https://slidge.
|
770
|
+
Refer to [the docs](https://slidge.im/docs/slidge/main/admin/install.html) for details.
|
770
771
|
|
771
772
|
About privacy
|
772
773
|
-------------
|
@@ -1,24 +1,24 @@
|
|
1
1
|
slidge/__init__.py,sha256=S0tUjqpZlzsr8G4Y_1Xt-KCYB07qaknTB0OwHU8k29U,1587
|
2
2
|
slidge/__main__.py,sha256=ydjUklOoavS4YlGfjRX_8BQN2DaSbaXPMi47RkOgcFI,37
|
3
|
-
slidge/__version__.py,sha256=
|
3
|
+
slidge/__version__.py,sha256=4bAi8qOyNOCy78XyBLZqa2BfhBAl80d4H4U1rf4i8-k,165
|
4
4
|
slidge/main.py,sha256=vMJzhvUxbeuIXuHxXXs6lm_ShBjXiS9B5Li5Ge4vWPo,6238
|
5
5
|
slidge/migration.py,sha256=4BJmPIRB56_WIhRTqBFIIBXuvnhhBjjOMl4CE7jY6oc,1541
|
6
6
|
slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
|
8
8
|
slidge/command/adhoc.py,sha256=-AO4h1N6owSuuqZon5tDL29O6qmEeAd1pcPjGCkzKRs,10065
|
9
9
|
slidge/command/admin.py,sha256=TYrzgCIhjcTIwl1IUaFlUd3D98SPyao10gB20zo8b3Q,6187
|
10
|
-
slidge/command/base.py,sha256=
|
10
|
+
slidge/command/base.py,sha256=EDcEl5dJcooSmLarXI2fmBq6QtU7h-7MOM3DDsxXmTU,13447
|
11
11
|
slidge/command/categories.py,sha256=vF0KGDV9sEn8TNkcMoDRw-u3gEyNHSXghOU2JRHQtKs,351
|
12
12
|
slidge/command/chat_command.py,sha256=z-4qp03rK7kCh3_kEozDViwkDg_hVjHvRCiYYJxedBQ,11153
|
13
13
|
slidge/command/register.py,sha256=BduDI31Kx8CbWWEdjybimTA5Wcfhn-Jkt8sSPsySCpo,6724
|
14
14
|
slidge/command/user.py,sha256=aksfkRUK7xj9n0XM-IfUSS5LrTp0qIHt5K2UkBBT1UE,12099
|
15
15
|
slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
|
16
|
-
slidge/contact/contact.py,sha256=
|
16
|
+
slidge/contact/contact.py,sha256=SiFeDoI1zuGKhVoK8O_Jm1ch9jwOsRINKgt1gijrmcc,23121
|
17
17
|
slidge/contact/roster.py,sha256=x3speGdHbZ-VTLoQLQW4s53rBeBvW87W8ZibCCZSLDA,10300
|
18
18
|
slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
|
19
|
-
slidge/core/config.py,sha256=
|
20
|
-
slidge/core/gateway.py,sha256=
|
21
|
-
slidge/core/pubsub.py,sha256=
|
19
|
+
slidge/core/config.py,sha256=9oIrXYB4Fx9uVQkMYDswrd0xr0ieEH8r1EkGym-AxBE,8060
|
20
|
+
slidge/core/gateway.py,sha256=S2fLp_KLPyoixlTQzvlrlus55dHFTYp-WkLZNSWw9mE,37022
|
21
|
+
slidge/core/pubsub.py,sha256=BoeYE__ptmRAn4x55Hn_6JWRA4nM-XJgDemG5Cy5kN4,11959
|
22
22
|
slidge/core/session.py,sha256=nQexpCd1jlHOhQPnFI4ri-5odp3N2pU5HO4l7WFetZY,28148
|
23
23
|
slidge/core/dispatcher/__init__.py,sha256=1EXcjXietUKlxEqdrCWCV3xZ3q_DSsjHoqWrPMbtYao,84
|
24
24
|
slidge/core/dispatcher/caps.py,sha256=vzCAXo_bhALuLEpJWtyJTzVfWx96g1AsWD8_wkoDl0Y,2028
|
@@ -40,22 +40,22 @@ slidge/core/dispatcher/muc/misc.py,sha256=bHBjMC-Pu3jR5hAPGMzXf-C05UbACIwg38YbJU
|
|
40
40
|
slidge/core/dispatcher/muc/owner.py,sha256=1a6YV7b_mmi1jC6q1ko8weeL8imQA-s-hYGPLIHd10I,3308
|
41
41
|
slidge/core/dispatcher/muc/ping.py,sha256=lb1VQPhiUPZ19KhbofRXMVCcY6wwQ2w-asnqtANaAwA,1660
|
42
42
|
slidge/core/mixins/__init__.py,sha256=muReAzgvENgMvlfm0Fpe6BQFfm2EMjoDe9ZhGgo6Vig,627
|
43
|
-
slidge/core/mixins/attachment.py,sha256=
|
43
|
+
slidge/core/mixins/attachment.py,sha256=rZcipXiGgo-8klumBvfgrSsU_rmS6cl1zx-zev_FZRg,20174
|
44
44
|
slidge/core/mixins/avatar.py,sha256=BVOeH5j5tsPJ0IHUcB5ozpyh02TBPKiZMd9MYizDokA,8136
|
45
45
|
slidge/core/mixins/base.py,sha256=MOd-pas38_52VawQVlxWtBtmTKC6My9G0ZaCeQxOJbs,748
|
46
46
|
slidge/core/mixins/db.py,sha256=5Qpegd7D8e5TLXLLINYcf_DuVdN-7wNmsfztUuFYPcU,442
|
47
47
|
slidge/core/mixins/disco.py,sha256=jk3Z1B6zTuisHv8VKNRJodIo0ee5btYHh2ZrlflPj_Q,3670
|
48
48
|
slidge/core/mixins/lock.py,sha256=Vf1rrkbyNbSprr38WGfZiMgTB7AdbqH8ppFHY8N2yXE,975
|
49
|
-
slidge/core/mixins/message.py,sha256=
|
49
|
+
slidge/core/mixins/message.py,sha256=0dPpDQwkdAdirUodKpb9Ad7mkr5meWc7S3lf0sXPYnc,7994
|
50
50
|
slidge/core/mixins/message_maker.py,sha256=TcCutHi0sIwL6beJNkN7XyR0aDIbA0xZyxd2Gc9ulG4,6022
|
51
51
|
slidge/core/mixins/message_text.py,sha256=pCY4tezEuwB2ZuUyUi72i4v9AJkxp_SWF1jrFsn94Ns,8096
|
52
52
|
slidge/core/mixins/presence.py,sha256=yywo6KAw8C7GaZSMrSMuioNfhW08MrnobHt8XbHd0q8,7891
|
53
53
|
slidge/core/mixins/recipient.py,sha256=b0uFnpym-hOFgYxGjXT1xQcZ4YRbDSBftPcNWLzSwEI,1336
|
54
54
|
slidge/db/__init__.py,sha256=EBDH1JSEhgqYcli2Bw11CRC749wJk8AOucgBzmhDSvU,105
|
55
|
-
slidge/db/avatar.py,sha256=
|
55
|
+
slidge/db/avatar.py,sha256=z5e72STv8PdN6zkNyKlLqF7NFxHwCa6IjwgFpzu5ghE,8033
|
56
56
|
slidge/db/meta.py,sha256=v1Jf-npZ28QwdGpsLQWLBHEbEP3-jnPrygRg05tJ_Iw,1831
|
57
57
|
slidge/db/models.py,sha256=0NUJfa3lPKHhwV2zE4p7QVYCVs3yn9egFg2u9mssk5c,13964
|
58
|
-
slidge/db/store.py,sha256=
|
58
|
+
slidge/db/store.py,sha256=A2F8QJ88INMSdw0S8G5wDAQJFjwpeExpLuwHu8T3ZHU,46904
|
59
59
|
slidge/db/alembic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
60
|
slidge/db/alembic/env.py,sha256=hsBlRNs0zF5diSHGRSa8Fi3qRVQDA2rJdR41AEIdvxc,1642
|
61
61
|
slidge/db/alembic/old_user_store.py,sha256=zFOv0JEWQQK0_TMRlU4Z0G5Mc9pxvEErLyOzXmRAe5Q,5209
|
@@ -80,7 +80,7 @@ slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py,sha2
|
|
80
80
|
slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
|
81
81
|
slidge/group/archive.py,sha256=IPqklzo0UN3lPHckfsKW9c4nl3m_9XGY4u0eehrhe8k,5281
|
82
82
|
slidge/group/bookmarks.py,sha256=AvFL34bEX6n3OP1Np309T5hrLK9GnjkjdyLJ3uiLZyc,6616
|
83
|
-
slidge/group/participant.py,sha256=
|
83
|
+
slidge/group/participant.py,sha256=tGGcAkdcK6aob1YP8e9ODbdK2_dGmFNH0F2x-gHyc4M,17611
|
84
84
|
slidge/group/room.py,sha256=aJ-VIYACuEuoyKDsBFxsUZFoVpd265i0mzTOOHCNTPg,46849
|
85
85
|
slidge/slixfix/__init__.py,sha256=aEXtmxMgxQWsUoDV5NSxZKwb-Hml5XeR2FMJlnaDUng,4324
|
86
86
|
slidge/slixfix/delivery_receipt.py,sha256=3bWdZH3-X3CZJXmnI_TpjkTUUK-EY4Ktm78lW0-40fc,1366
|
@@ -111,8 +111,8 @@ slidge/util/db.py,sha256=4LxZj8oBYgiSnyBUnF_ALjr0TblkfNQq_p28sCfkHMY,242
|
|
111
111
|
slidge/util/test.py,sha256=l1VHBsw5Uzk2t7wtkfb9kWvtehcYhw1t_d567JAJFKA,14135
|
112
112
|
slidge/util/types.py,sha256=R_xfS5mRL0XUJIoDpnaAkZlTOoLPerduXBFftaVwIAI,5489
|
113
113
|
slidge/util/util.py,sha256=An4BRIHktZGXnu4kCwaKYaSye_PlyuxEm_4SC9YvPhc,9594
|
114
|
-
slidge-0.2.
|
115
|
-
slidge-0.2.
|
116
|
-
slidge-0.2.
|
117
|
-
slidge-0.2.
|
118
|
-
slidge-0.2.
|
114
|
+
slidge-0.2.5.dist-info/METADATA,sha256=qPrPddCJQeL3747-F2abvx04v1bGPzyFJiLHX8Xjx0E,44856
|
115
|
+
slidge-0.2.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
116
|
+
slidge-0.2.5.dist-info/entry_points.txt,sha256=py3_x834fFJ2TEzPd18Wt2DnysdAfuVqJ5zzBrXbAZs,44
|
117
|
+
slidge-0.2.5.dist-info/top_level.txt,sha256=2LRjDYHaGZ5ieCMF8xy58JIiabRMzX-MGMbCZwfE17c,7
|
118
|
+
slidge-0.2.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|