slidge 0.1.0rc1__py3-none-any.whl → 0.1.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. slidge/__init__.py +54 -31
  2. slidge/__main__.py +51 -5
  3. slidge/command/__init__.py +28 -0
  4. slidge/command/adhoc.py +258 -0
  5. slidge/command/admin.py +193 -0
  6. slidge/command/base.py +441 -0
  7. slidge/command/categories.py +3 -0
  8. slidge/command/chat_command.py +288 -0
  9. slidge/command/register.py +179 -0
  10. slidge/command/user.py +250 -0
  11. slidge/contact/__init__.py +8 -0
  12. slidge/contact/contact.py +452 -0
  13. slidge/contact/roster.py +192 -0
  14. slidge/core/__init__.py +2 -0
  15. slidge/core/cache.py +121 -39
  16. slidge/core/config.py +116 -11
  17. slidge/core/gateway/__init__.py +3 -0
  18. slidge/core/gateway/base.py +895 -0
  19. slidge/core/gateway/caps.py +63 -0
  20. slidge/core/gateway/delivery_receipt.py +52 -0
  21. slidge/core/gateway/disco.py +80 -0
  22. slidge/core/gateway/mam.py +75 -0
  23. slidge/core/gateway/muc_admin.py +35 -0
  24. slidge/core/gateway/ping.py +66 -0
  25. slidge/core/gateway/presence.py +95 -0
  26. slidge/core/gateway/registration.py +53 -0
  27. slidge/core/gateway/search.py +102 -0
  28. slidge/core/gateway/session_dispatcher.py +795 -0
  29. slidge/core/gateway/vcard_temp.py +130 -0
  30. slidge/core/mixins/__init__.py +9 -1
  31. slidge/core/mixins/attachment.py +506 -0
  32. slidge/core/mixins/avatar.py +167 -0
  33. slidge/core/mixins/base.py +6 -19
  34. slidge/core/mixins/disco.py +66 -15
  35. slidge/core/mixins/lock.py +31 -0
  36. slidge/core/mixins/message.py +254 -252
  37. slidge/core/mixins/message_maker.py +154 -0
  38. slidge/core/mixins/presence.py +128 -31
  39. slidge/core/mixins/recipient.py +43 -0
  40. slidge/core/pubsub.py +275 -116
  41. slidge/core/session.py +586 -518
  42. slidge/group/__init__.py +10 -0
  43. slidge/group/archive.py +125 -0
  44. slidge/group/bookmarks.py +163 -0
  45. slidge/group/participant.py +458 -0
  46. slidge/group/room.py +1103 -0
  47. slidge/migration.py +18 -0
  48. slidge/slixfix/__init__.py +68 -0
  49. slidge/{util/xep_0050 → slixfix/link_preview}/__init__.py +4 -5
  50. slidge/slixfix/link_preview/link_preview.py +17 -0
  51. slidge/slixfix/link_preview/stanza.py +99 -0
  52. slidge/slixfix/roster.py +60 -0
  53. slidge/{util → slixfix}/xep_0077/register.py +1 -2
  54. slidge/slixfix/xep_0077/stanza.py +104 -0
  55. slidge/{util → slixfix}/xep_0100/gateway.py +17 -12
  56. slidge/slixfix/xep_0153/__init__.py +10 -0
  57. slidge/slixfix/xep_0153/stanza.py +25 -0
  58. slidge/slixfix/xep_0153/vcard_avatar.py +23 -0
  59. slidge/slixfix/xep_0264/__init__.py +5 -0
  60. slidge/slixfix/xep_0264/stanza.py +36 -0
  61. slidge/slixfix/xep_0264/thumbnail.py +23 -0
  62. slidge/slixfix/xep_0292/__init__.py +5 -0
  63. slidge/slixfix/xep_0292/vcard4.py +100 -0
  64. slidge/slixfix/xep_0313/__init__.py +12 -0
  65. slidge/slixfix/xep_0313/mam.py +262 -0
  66. slidge/slixfix/xep_0313/stanza.py +359 -0
  67. slidge/slixfix/xep_0317/__init__.py +5 -0
  68. slidge/slixfix/xep_0317/hats.py +17 -0
  69. slidge/slixfix/xep_0317/stanza.py +28 -0
  70. slidge/{util → slixfix}/xep_0356_old/privilege.py +9 -7
  71. slidge/slixfix/xep_0424/__init__.py +9 -0
  72. slidge/slixfix/xep_0424/retraction.py +77 -0
  73. slidge/slixfix/xep_0424/stanza.py +28 -0
  74. slidge/slixfix/xep_0490/__init__.py +8 -0
  75. slidge/slixfix/xep_0490/mds.py +47 -0
  76. slidge/slixfix/xep_0490/stanza.py +17 -0
  77. slidge/util/__init__.py +4 -6
  78. slidge/util/archive_msg.py +61 -0
  79. slidge/util/conf.py +25 -4
  80. slidge/util/db.py +23 -69
  81. slidge/util/schema.sql +126 -0
  82. slidge/util/sql.py +508 -0
  83. slidge/util/test.py +136 -86
  84. slidge/util/types.py +155 -14
  85. slidge/util/util.py +225 -51
  86. slidge-0.1.2.dist-info/METADATA +111 -0
  87. slidge-0.1.2.dist-info/RECORD +96 -0
  88. {slidge-0.1.0rc1.dist-info → slidge-0.1.2.dist-info}/WHEEL +1 -1
  89. slidge/core/adhoc.py +0 -492
  90. slidge/core/chat_command.py +0 -197
  91. slidge/core/contact.py +0 -441
  92. slidge/core/disco.py +0 -59
  93. slidge/core/gateway.py +0 -899
  94. slidge/core/muc/__init__.py +0 -3
  95. slidge/core/muc/bookmarks.py +0 -74
  96. slidge/core/muc/participant.py +0 -152
  97. slidge/core/muc/room.py +0 -348
  98. slidge/plugins/discord/__init__.py +0 -121
  99. slidge/plugins/discord/client.py +0 -121
  100. slidge/plugins/discord/session.py +0 -172
  101. slidge/plugins/dummy.py +0 -334
  102. slidge/plugins/facebook.py +0 -591
  103. slidge/plugins/hackernews.py +0 -209
  104. slidge/plugins/mattermost/__init__.py +0 -1
  105. slidge/plugins/mattermost/api.py +0 -288
  106. slidge/plugins/mattermost/gateway.py +0 -417
  107. slidge/plugins/mattermost/websocket.py +0 -248
  108. slidge/plugins/signal/__init__.py +0 -4
  109. slidge/plugins/signal/config.py +0 -4
  110. slidge/plugins/signal/contact.py +0 -104
  111. slidge/plugins/signal/gateway.py +0 -379
  112. slidge/plugins/signal/group.py +0 -76
  113. slidge/plugins/signal/session.py +0 -515
  114. slidge/plugins/signal/txt.py +0 -13
  115. slidge/plugins/signal/util.py +0 -32
  116. slidge/plugins/skype.py +0 -310
  117. slidge/plugins/steam.py +0 -400
  118. slidge/plugins/telegram/__init__.py +0 -6
  119. slidge/plugins/telegram/client.py +0 -325
  120. slidge/plugins/telegram/config.py +0 -21
  121. slidge/plugins/telegram/contact.py +0 -154
  122. slidge/plugins/telegram/gateway.py +0 -182
  123. slidge/plugins/telegram/group.py +0 -184
  124. slidge/plugins/telegram/session.py +0 -275
  125. slidge/plugins/telegram/util.py +0 -153
  126. slidge/plugins/whatsapp/__init__.py +0 -6
  127. slidge/plugins/whatsapp/config.py +0 -17
  128. slidge/plugins/whatsapp/contact.py +0 -33
  129. slidge/plugins/whatsapp/event.go +0 -455
  130. slidge/plugins/whatsapp/gateway.go +0 -156
  131. slidge/plugins/whatsapp/gateway.py +0 -69
  132. slidge/plugins/whatsapp/go.mod +0 -17
  133. slidge/plugins/whatsapp/go.sum +0 -22
  134. slidge/plugins/whatsapp/session.go +0 -371
  135. slidge/plugins/whatsapp/session.py +0 -370
  136. slidge/util/xep_0030/__init__.py +0 -13
  137. slidge/util/xep_0030/disco.py +0 -811
  138. slidge/util/xep_0030/stanza/__init__.py +0 -7
  139. slidge/util/xep_0030/stanza/info.py +0 -270
  140. slidge/util/xep_0030/stanza/items.py +0 -147
  141. slidge/util/xep_0030/static.py +0 -467
  142. slidge/util/xep_0050/adhoc.py +0 -631
  143. slidge/util/xep_0050/stanza.py +0 -180
  144. slidge/util/xep_0077/stanza.py +0 -71
  145. slidge/util/xep_0292/__init__.py +0 -1
  146. slidge/util/xep_0292/stanza.py +0 -167
  147. slidge/util/xep_0292/vcard4.py +0 -74
  148. slidge/util/xep_0356/__init__.py +0 -7
  149. slidge/util/xep_0356/permissions.py +0 -35
  150. slidge/util/xep_0356/privilege.py +0 -160
  151. slidge/util/xep_0356/stanza.py +0 -44
  152. slidge/util/xep_0461/__init__.py +0 -6
  153. slidge/util/xep_0461/reply.py +0 -48
  154. slidge/util/xep_0461/stanza.py +0 -80
  155. slidge-0.1.0rc1.dist-info/METADATA +0 -171
  156. slidge-0.1.0rc1.dist-info/RECORD +0 -99
  157. /slidge/{plugins/__init__.py → py.typed} +0 -0
  158. /slidge/{util → slixfix}/xep_0077/__init__.py +0 -0
  159. /slidge/{util → slixfix}/xep_0100/__init__.py +0 -0
  160. /slidge/{util → slixfix}/xep_0100/stanza.py +0 -0
  161. /slidge/{util → slixfix}/xep_0356_old/__init__.py +0 -0
  162. /slidge/{util → slixfix}/xep_0356_old/stanza.py +0 -0
  163. {slidge-0.1.0rc1.dist-info → slidge-0.1.2.dist-info}/LICENSE +0 -0
  164. {slidge-0.1.0rc1.dist-info → slidge-0.1.2.dist-info}/entry_points.txt +0 -0
slidge/util/util.py CHANGED
@@ -1,68 +1,58 @@
1
- import dataclasses
2
1
  import logging
2
+ import mimetypes
3
3
  import re
4
+ import subprocess
5
+ import warnings
4
6
  from abc import ABCMeta
5
- from typing import Collection, Generic, Optional, TypeVar
7
+ from pathlib import Path
8
+ from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Type
6
9
 
7
- from .types import FieldType
10
+ from .types import Mention, ResourceDict
8
11
 
12
+ if TYPE_CHECKING:
13
+ from ..contact.contact import LegacyContact
9
14
 
10
- @dataclasses.dataclass
11
- class FormField:
12
- """
13
- Represents a field of the form that a user will see when registering to the gateway
14
- via their XMPP client.
15
- """
16
-
17
- var: str = ""
18
- """
19
- Internal name of the field, will be used to retrieve via :py:attr:`slidge.GatewayUser.registration_form`
20
- """
21
- label: Optional[str] = None
22
- """Description of the field that the aspiring user will see"""
23
- required: bool = False
24
- """Whether this field is mandatory or not"""
25
- private: bool = False
26
- """
27
- For sensitive info that should not be displayed on screen while the user types.
28
- Forces field_type to "text-private"
29
- """
30
- type: FieldType = "text-single"
31
- """Type of the field, see `XEP-0004 <https://xmpp.org/extensions/xep-0004.html#protocol-fieldtypes>`_"""
32
- value: str = ""
33
- """Pre-filled value. Will be automatically pre-filled if a registered user modifies their subscription"""
34
- options: Optional[list[dict[str, str]]] = None
35
-
36
- def dict(self):
37
- return dataclasses.asdict(self)
15
+ try:
16
+ import magic
17
+ except ImportError as e:
18
+ magic = None # type:ignore
19
+ logging.warning(
20
+ (
21
+ "Libmagic is not available: %s. "
22
+ "It's OK if you don't use fix-filename-suffix-mime-type."
23
+ ),
24
+ e,
25
+ )
38
26
 
39
- def __post_init__(self):
40
- if self.private:
41
- self.type = "text-private"
42
27
 
28
+ def fix_suffix(path: Path, mime_type: Optional[str], file_name: Optional[str]):
29
+ guessed = magic.from_file(path, mime=True)
30
+ if guessed == mime_type:
31
+ log.debug("Magic and given MIME match")
32
+ else:
33
+ log.debug("Magic (%s) and given MIME (%s) differ", guessed, mime_type)
34
+ mime_type = guessed
43
35
 
44
- KeyType = TypeVar("KeyType")
45
- ValueType = TypeVar("ValueType")
36
+ valid_suffix_list = mimetypes.guess_all_extensions(mime_type, strict=False)
46
37
 
38
+ if file_name:
39
+ name = Path(file_name)
40
+ else:
41
+ name = Path(path.name)
47
42
 
48
- class BiDict(Generic[KeyType, ValueType], dict[KeyType, ValueType]):
49
- def __init__(self, *args, **kwargs):
50
- super().__init__(*args, **kwargs)
51
- self.inverse: dict[ValueType, KeyType] = {}
52
- for key, value in self.items():
53
- self.inverse[value] = key
43
+ suffix = name.suffix
54
44
 
55
- def __setitem__(self, key: KeyType, value: ValueType):
56
- if key in self:
57
- del self.inverse[self[key]]
58
- super().__setitem__(key, value)
59
- self.inverse[value] = key
45
+ if suffix in valid_suffix_list:
46
+ log.debug("Suffix %s is in %s", suffix, valid_suffix_list)
47
+ return name
60
48
 
49
+ valid_suffix = mimetypes.guess_extension(mime_type.split(";")[0], strict=False)
50
+ if valid_suffix is None:
51
+ log.debug("No valid suffix found")
52
+ return name
61
53
 
62
- @dataclasses.dataclass
63
- class SearchResult:
64
- fields: Collection[FormField]
65
- items: Collection[dict[str, str]]
54
+ log.debug("Changing suffix of %s to %s", file_name or path.name, valid_suffix)
55
+ return name.with_suffix(valid_suffix)
66
56
 
67
57
 
68
58
  class SubclassableOnce(type):
@@ -118,4 +108,188 @@ def is_valid_phone_number(phone: Optional[str]):
118
108
  return match[0] == phone
119
109
 
120
110
 
111
+ def strip_illegal_chars(s: str):
112
+ return ILLEGAL_XML_CHARS_RE.sub("", s)
113
+
114
+
115
+ # from https://stackoverflow.com/a/64570125/5902284 and Link Mauve
116
+ ILLEGAL = [
117
+ (0x00, 0x08),
118
+ (0x0B, 0x0C),
119
+ (0x0E, 0x1F),
120
+ (0x7F, 0x84),
121
+ (0x86, 0x9F),
122
+ (0xFDD0, 0xFDDF),
123
+ (0xFFFE, 0xFFFF),
124
+ (0x1FFFE, 0x1FFFF),
125
+ (0x2FFFE, 0x2FFFF),
126
+ (0x3FFFE, 0x3FFFF),
127
+ (0x4FFFE, 0x4FFFF),
128
+ (0x5FFFE, 0x5FFFF),
129
+ (0x6FFFE, 0x6FFFF),
130
+ (0x7FFFE, 0x7FFFF),
131
+ (0x8FFFE, 0x8FFFF),
132
+ (0x9FFFE, 0x9FFFF),
133
+ (0xAFFFE, 0xAFFFF),
134
+ (0xBFFFE, 0xBFFFF),
135
+ (0xCFFFE, 0xCFFFF),
136
+ (0xDFFFE, 0xDFFFF),
137
+ (0xEFFFE, 0xEFFFF),
138
+ (0xFFFFE, 0xFFFFF),
139
+ (0x10FFFE, 0x10FFFF),
140
+ ]
141
+
142
+ ILLEGAL_RANGES = [rf"{chr(low)}-{chr(high)}" for (low, high) in ILLEGAL]
143
+ XML_ILLEGAL_CHARACTER_REGEX = "[" + "".join(ILLEGAL_RANGES) + "]"
144
+ ILLEGAL_XML_CHARS_RE = re.compile(XML_ILLEGAL_CHARACTER_REGEX)
145
+
146
+
147
+ # from https://stackoverflow.com/a/35804945/5902284
148
+ def addLoggingLevel(
149
+ levelName: str = "TRACE", levelNum: int = logging.DEBUG - 5, methodName=None
150
+ ):
151
+ """
152
+ Comprehensively adds a new logging level to the `logging` module and the
153
+ currently configured logging class.
154
+
155
+ `levelName` becomes an attribute of the `logging` module with the value
156
+ `levelNum`. `methodName` becomes a convenience method for both `logging`
157
+ itself and the class returned by `logging.getLoggerClass()` (usually just
158
+ `logging.Logger`). If `methodName` is not specified, `levelName.lower()` is
159
+ used.
160
+
161
+ To avoid accidental clobberings of existing attributes, this method will
162
+ raise an `AttributeError` if the level name is already an attribute of the
163
+ `logging` module or if the method name is already present
164
+
165
+ Example
166
+ -------
167
+ >>> addLoggingLevel('TRACE', logging.DEBUG - 5)
168
+ >>> logging.getLogger(__name__).setLevel("TRACE")
169
+ >>> logging.getLogger(__name__).trace('that worked')
170
+ >>> logging.trace('so did this')
171
+ >>> logging.TRACE
172
+ 5
173
+
174
+ """
175
+ if not methodName:
176
+ methodName = levelName.lower()
177
+
178
+ if hasattr(logging, levelName):
179
+ log.debug("{} already defined in logging module".format(levelName))
180
+ return
181
+ if hasattr(logging, methodName):
182
+ log.debug("{} already defined in logging module".format(methodName))
183
+ return
184
+ if hasattr(logging.getLoggerClass(), methodName):
185
+ log.debug("{} already defined in logger class".format(methodName))
186
+ return
187
+
188
+ # This method was inspired by the answers to Stack Overflow post
189
+ # http://stackoverflow.com/q/2183233/2988730, especially
190
+ # http://stackoverflow.com/a/13638084/2988730
191
+ def logForLevel(self, message, *args, **kwargs):
192
+ if self.isEnabledFor(levelNum):
193
+ self._log(levelNum, message, args, **kwargs)
194
+
195
+ def logToRoot(message, *args, **kwargs):
196
+ logging.log(levelNum, message, *args, **kwargs)
197
+
198
+ logging.addLevelName(levelNum, levelName)
199
+ setattr(logging, levelName, levelNum)
200
+ setattr(logging.getLoggerClass(), methodName, logForLevel)
201
+ setattr(logging, methodName, logToRoot)
202
+
203
+
204
+ class SlidgeLogger(logging.Logger):
205
+ def trace(self):
206
+ pass
207
+
208
+
121
209
  log = logging.getLogger(__name__)
210
+
211
+
212
+ def get_version():
213
+ try:
214
+ git = subprocess.check_output(
215
+ ["git", "rev-parse", "HEAD"], stderr=subprocess.DEVNULL
216
+ ).decode()
217
+ except (FileNotFoundError, subprocess.CalledProcessError):
218
+ pass
219
+ else:
220
+ return "git-" + git[:10]
221
+
222
+ return "NO_VERSION"
223
+
224
+
225
+ def merge_resources(resources: dict[str, ResourceDict]) -> Optional[ResourceDict]:
226
+ if len(resources) == 0:
227
+ return None
228
+
229
+ if len(resources) == 1:
230
+ return next(iter(resources.values()))
231
+
232
+ by_priority = sorted(resources.values(), key=lambda r: r["priority"], reverse=True)
233
+
234
+ if any(r["show"] == "" for r in resources.values()):
235
+ # if a client is "available", we're "available"
236
+ show = ""
237
+ else:
238
+ for r in by_priority:
239
+ if r["show"]:
240
+ show = r["show"]
241
+ break
242
+ else:
243
+ raise RuntimeError()
244
+
245
+ # if there are different statuses, we use the highest priority one,
246
+ # but we ignore resources without status, even with high priority
247
+ status = ""
248
+ for r in by_priority:
249
+ if r["status"]:
250
+ status = r["status"]
251
+ break
252
+
253
+ return {
254
+ "show": show, # type:ignore
255
+ "status": status,
256
+ "priority": 0,
257
+ }
258
+
259
+
260
+ def remove_emoji_variation_selector_16(emoji: str):
261
+ # this is required for compatibility with dino, and maybe other future clients?
262
+ return bytes(emoji, encoding="utf-8").replace(b"\xef\xb8\x8f", b"").decode()
263
+
264
+
265
+ def deprecated(name: str, new: Callable):
266
+ # @functools.wraps
267
+ def wrapped(*args, **kwargs):
268
+ warnings.warn(
269
+ f"{name} is deprecated. Use {new.__name__} instead",
270
+ category=DeprecationWarning,
271
+ )
272
+ return new(*args, **kwargs)
273
+
274
+ return wrapped
275
+
276
+
277
+ def dict_to_named_tuple(data: dict, cls: Type[NamedTuple]):
278
+ return cls(*(data.get(f) for f in cls._fields)) # type:ignore
279
+
280
+
281
+ def replace_mentions(
282
+ text: str,
283
+ mentions: Optional[list[Mention]],
284
+ mapping: Callable[["LegacyContact"], str],
285
+ ):
286
+ if not mentions:
287
+ return text
288
+
289
+ cursor = 0
290
+ pieces = []
291
+ for mention in mentions:
292
+ pieces.extend([text[cursor : mention.start], mapping(mention.contact)])
293
+ cursor = mention.end
294
+ pieces.append(text[cursor:])
295
+ return "".join(pieces)
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.1
2
+ Name: slidge
3
+ Version: 0.1.2
4
+ Summary: XMPP bridging framework
5
+ Home-page: https://sr.ht/~nicoco/slidge/
6
+ License: AGPL-3.0-or-later
7
+ Author: Nicolas Cedilnik
8
+ Author-email: nicoco@nicoco.fr
9
+ Requires-Python: >=3.9,<4.0
10
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Requires-Dist: ConfigArgParse (>=1.5.3,<2.0.0)
16
+ Requires-Dist: Pillow (>=10,<11)
17
+ Requires-Dist: aiohttp[speedups] (>=3.8.3,<4.0.0)
18
+ Requires-Dist: blurhash-python (>=1.2.1,<2.0.0)
19
+ Requires-Dist: pickle-secure (>=0.99.9,<0.100.0)
20
+ Requires-Dist: python-magic (>=0.4.27,<0.5.0)
21
+ Requires-Dist: qrcode (>=7.4.1,<8.0.0)
22
+ Requires-Dist: slixmpp (>=1.8.5,<2.0.0)
23
+ Project-URL: Documentation, https://slidge.im/
24
+ Project-URL: Repository, https://git.sr.ht/~nicoco/slidge/
25
+ Description-Content-Type: text/markdown
26
+
27
+ ![Slidge logo](https://git.sr.ht/~nicoco/slidge/blob/master/dev/assets/slidge-color-small.png)
28
+
29
+ [Home](https://sr.ht/~nicoco/slidge) |
30
+ [Docs](https://slidge.im/core) |
31
+ [Source](https://sr.ht/~nicoco/slidge/sources) |
32
+ [Issues](https://sr.ht/~nicoco/slidge/trackers) |
33
+ [Patches](https://lists.sr.ht/~nicoco/public-inbox) |
34
+ [Chat](xmpp:slidge@conference.nicoco.fr?join)
35
+
36
+ [![builds.sr.ht status](https://builds.sr.ht/~nicoco/slidge/commits/master/ci.yml.svg)](https://builds.sr.ht/~nicoco/slidge/commits/master/ci.yml?)
37
+ [![coverage](https://slidge.im/coverage.svg)](https://slidge.im/coverage)
38
+ [![pypi](https://badge.fury.io/py/slidge.svg)](https://pypi.org/project/slidge/)
39
+
40
+ Slidge is an XMPP (puppeteer) gateway library in python.
41
+ It makes
42
+ [writing gateways to other chat networks](https://slidge.im/core/dev/tutorial.html)
43
+ (*legacy modules*) as frictionless as possible.
44
+ It supports fancy IM features, such as
45
+ [(emoji) reactions](https://xmpp.org/extensions/xep-0444.html),
46
+ [replies](https://xmpp.org/extensions/xep-0461.html), and
47
+ [retractions](https://xmpp.org/extensions/xep-0424.html).
48
+ The full list of supported XEPs in on [xmpp.org](https://xmpp.org/software/slidge/).
49
+
50
+ Slidge is meant for gateway developers, if you are an XMPP server admin and
51
+ want to install gateways on your server, you are looking for one of these projects:
52
+
53
+ - [slidgnal](https://git.sr.ht/~nicoco/slidgnal) ([Signal](https://signal.org))
54
+ - [slidge-whatsapp](https://git.sr.ht/~nicoco/slidge-whatsapp) ([Whatsapp](https://whatsapp.com))
55
+ - [slidgram](https://git.sr.ht/~nicoco/slidgram) ([Telegram](https://telegram.org))
56
+ - [slidcord](https://git.sr.ht/~nicoco/slidcord) ([Discord](https://discord.com))
57
+ - [matteridge](https://git.sr.ht/~nicoco/matteridge) ([Mattermost](https://mattermost.com))
58
+ - [sleamdge](https://git.sr.ht/~nicoco/sleamdge) ([Steam](https://steamcommunity.com/))
59
+ - [skidge](https://git.sr.ht/~nicoco/skidge) ([Skype](https://skype.com/))
60
+ - [messlidger](https://git.sr.ht/~nicoco/messlidger) ([Facebook Messenger](https://messenger.com/))
61
+ - [matridge](https://git.sr.ht/~nicoco/matridge) ([Matrix](https://matrix.org/))
62
+ - [slidgevoipms](https://codeberg.org/boxedtoast/slidgevoipms) ([voip.ms](https://voip.ms/))
63
+
64
+ If you use debian, you might also be interested in the
65
+ [slidge-debian](https://git.sr.ht/~nicoco/slidge-debian)
66
+ bundle.
67
+
68
+ Status
69
+ ------
70
+
71
+ Slidge is **beta**-grade software. It support groups and 1:1 chats.
72
+
73
+ Try slidge and give us some
74
+ feedback, through the [MUC](xmpp:slidge@conference.nicoco.fr?join), the
75
+ [issue tracker](https://todo.sr.ht/~nicoco/slidge) or in the
76
+ [public inbox](https://lists.sr.ht/~nicoco/public-inbox).
77
+ Don't be shy!
78
+
79
+ Installation
80
+ ------------
81
+
82
+ Slidge is available on
83
+ [docker.io](https://hub.docker.com/u/nicocool84),
84
+ [pypi](https://pypi.org/project/slidge/) and as
85
+ [debian packages](https://slidge.im/core/admin/install.html#debian).
86
+ Refer to [the docs](https://slidge.im/core/admin/install.html) for details.
87
+
88
+ About privacy
89
+ -------------
90
+
91
+ Slidge (and most if not all XMPP gateway that I know of) will break
92
+ end-to-end encryption, or more precisely one of the 'ends' become the
93
+ gateway itself. If privacy is a major concern for you, my advice would
94
+ be to:
95
+
96
+ - use XMPP + OMEMO
97
+ - self-host your gateways
98
+ - have your gateways hosted by someone you know AFK and trust
99
+
100
+ Related projects
101
+ ----------------
102
+
103
+ - [Spectrum](https://www.spectrum.im/)
104
+ - [telegabber](https://dev.narayana.im/narayana/telegabber)
105
+ - [biboumi](https://biboumi.louiz.org/)
106
+ - [Bifröst](https://github.com/matrix-org/matrix-bifrost)
107
+ - [Mautrix](https://github.com/mautrix)
108
+ - [matterbridge](https://github.com/42wim/matterbridge)
109
+
110
+ Thank you, [Trung](https://trung.fun/), for the slidge logo!
111
+
@@ -0,0 +1,96 @@
1
+ slidge/__init__.py,sha256=ykOurwgxvgYkuEim5t3M5zdbgyFyVs21SE20d4XkCKY,1624
2
+ slidge/__main__.py,sha256=QCG_5nFBtMTsX_au_FYKebU3TIog0aZipNmxLYRmloI,5804
3
+ slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
4
+ slidge/command/adhoc.py,sha256=ga1i36m2Heg10h9Elb9U5dBDRT-Q5lNk4HM64nzvKoU,9188
5
+ slidge/command/admin.py,sha256=aZCuQFfAWqOO8RgQu_EzKBg1yjOtohYz6r9Vtg9KQ0Y,5759
6
+ slidge/command/base.py,sha256=ht0Rgq4RCx5hHthATPbbWIbX2VqfFKSUolzcHpncxk0,13073
7
+ slidge/command/categories.py,sha256=BJCfaga2qoAxnHfgHD7I_RKZuBA5nnNOukkWHJwsUFE,99
8
+ slidge/command/chat_command.py,sha256=kMnxrzmD7LhWgyO1w9Rgz1eA7PhfAJ2Rf34YWjoKrwQ,9975
9
+ slidge/command/register.py,sha256=uU8_21do7_uSl6JpvjTu7RHypjIxOPkKFX9tHgZVGGc,6014
10
+ slidge/command/user.py,sha256=2mpIfjVJt7x9AZHQq4zcOlJGk8WVahUQhh4TYiW9T2Q,8781
11
+ slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
12
+ slidge/contact/contact.py,sha256=9umQ-fCXDHU4IgkC3kuuejqU1Bnr8GV_xfCIwXUR6PE,16101
13
+ slidge/contact/roster.py,sha256=XhcAJEs_j7VIn88DVmPReXK2VopzIQVoH2bwoeCqk_U,7489
14
+ slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
15
+ slidge/core/cache.py,sha256=Tkw8Bsor8zTN5wPIsBzxfnEk8GaOXMIauO4iBXxgv3M,5443
16
+ slidge/core/config.py,sha256=upZsWObT14foXc5HaXlOcZPLhGL2KSeK0K-QwPDHL3I,7392
17
+ slidge/core/gateway/__init__.py,sha256=rZckY2gAE-mon77_DSsAW1XtWqhBAETE2d4FqZ8pJXk,58
18
+ slidge/core/gateway/base.py,sha256=SOjoEV6MME2gGDS7oZgA3RdWBlqdrZeQs5Usf80ijcY,34645
19
+ slidge/core/gateway/caps.py,sha256=Qosd3cZ356mGzzQkdP6Y8OZ5c0l7H3Lr2wptoFrD1qU,1919
20
+ slidge/core/gateway/delivery_receipt.py,sha256=AT_9gvZrtWpSRsDJcYjE8CmF7TW-YBbUPdqNW5zWAdo,1352
21
+ slidge/core/gateway/disco.py,sha256=_ylFGQAzBvKSe1iB85uhBnRUXExExDrEaFa5MEM3E7Y,2230
22
+ slidge/core/gateway/mam.py,sha256=4appZbiaFICw1kySE-y1lgNzlUzY4jbgxC0IdGv87zw,2471
23
+ slidge/core/gateway/muc_admin.py,sha256=z2l4Zt0h-Z9WzEcA6MEiPNPrbYwggEqBVXpia5HtpLI,1033
24
+ slidge/core/gateway/ping.py,sha256=YUmreEyEw89l0M65D_AylL5oW4xj4lvJvhwucyiKofw,1753
25
+ slidge/core/gateway/presence.py,sha256=Ow2tWRx-tBL9mGeYRrHLboxD2CdJ32w9yor1kHZEL4U,2732
26
+ slidge/core/gateway/registration.py,sha256=KmxDFV3N01gCs_58Re9QIxJukYP7S3_i6IbukZxzEIs,1619
27
+ slidge/core/gateway/search.py,sha256=ZZPnZlTYFedsQAY-80ZX2el_oej6X7HfIwydYdTxl-o,3518
28
+ slidge/core/gateway/session_dispatcher.py,sha256=YNcyVhoe-iyGfCpjoMz9py9HCkZ_Wag48rx-jnyoVOw,29193
29
+ slidge/core/gateway/vcard_temp.py,sha256=uCSefV1D0Xx7Ex40t4uS0KHF7cbnq-xixAQQBxTtme8,4639
30
+ slidge/core/mixins/__init__.py,sha256=iAVi4gzekXIR2xDS8ic1gSguvBbfVSScWArM4t87L-U,368
31
+ slidge/core/mixins/attachment.py,sha256=yu7AzrRUCvKM_4AXYO1a83I4o_Sc8h3zteNRYOP2LgU,17808
32
+ slidge/core/mixins/avatar.py,sha256=f3zSWFbj5sEo8HzV5btKsqt-clr_s1IkO5XrOjl2sWE,5493
33
+ slidge/core/mixins/base.py,sha256=eWKV_9Io59roAt7BGRt6DKJgTxSaJEX4ptS9KneF32A,702
34
+ slidge/core/mixins/disco.py,sha256=SKPVRVq8NUcc-zerHit7_K3Xmo1yJF1ipYN9lhHUDBU,3935
35
+ slidge/core/mixins/lock.py,sha256=mVzwVVEoq1hrAMgGLh4K84BTLt7JTJ33B8HSGSorTdY,913
36
+ slidge/core/mixins/message.py,sha256=yK1f6SsngJR9mQQzPwFvnscvaH3ln7pqGSv7-omWeIE,14790
37
+ slidge/core/mixins/message_maker.py,sha256=cZy2eq87Cl019zVN_aay3Cxww9PUi1Z68QPorRcPJ2E,5606
38
+ slidge/core/mixins/presence.py,sha256=I4jAtJd2WIHQxqPBBKLIPB4aP09vjt8yYbY-u6ojfHk,7216
39
+ slidge/core/mixins/recipient.py,sha256=U-YppozUO8pA94jmD3-qmhkykTebPNaOVWc3JDPC9w8,1302
40
+ slidge/core/pubsub.py,sha256=u0KvRqsOcwyc2yapzDH4eNjeqrwo8jtUYLtjYjC9W3E,18268
41
+ slidge/core/session.py,sha256=xKyFxmi_tbp0WJNB7uJX_AENA2u1Pc0EzGr54ajmzfA,26134
42
+ slidge/group/__init__.py,sha256=yFt7cHqeaKIMN6f9ZyhhspOcJJvBtLedGv-iICG7lto,258
43
+ slidge/group/archive.py,sha256=5lnhUZ27RoVsYgcs-KiYiOLHZtB7VfRozLiTf0ZGNjM,3426
44
+ slidge/group/bookmarks.py,sha256=2uX7EiMlJJhYOnTXS1oJOchF5u_hFQAlp8VT2mcPqi0,5944
45
+ slidge/group/participant.py,sha256=CQnH3ayAO0MYVnVmeIehYU16gUByyjzwD0UlhIacq60,14908
46
+ slidge/group/room.py,sha256=I6cysvz8rfL6mZZ2AloYufJeG4FlDkEmESLH5oG8b-0,38972
47
+ slidge/migration.py,sha256=PPSjYMFsc9WGWWiSHWqUskpV_L9OJcrlecRf-Z0Vw_E,334
48
+ slidge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
+ slidge/slixfix/__init__.py,sha256=eYYLj3e4zJMRasjDlWxV4fe3zN0VJfwxbsc_rkOHefw,1777
50
+ slidge/slixfix/link_preview/__init__.py,sha256=TDPTSEH5FQxgGpQpQIde-D72AHg-6YVWG-tOj4KpKmU,290
51
+ slidge/slixfix/link_preview/link_preview.py,sha256=9PgdfnoyVMHnXS0w5OFp0wz3ku96Ck-HtRXbVUlDi1U,448
52
+ slidge/slixfix/link_preview/stanza.py,sha256=YAXoNw2MD0a3nzvldGKlvSemjUMbUEG23regzmj4Ntc,2664
53
+ slidge/slixfix/roster.py,sha256=PkoLroNkvmrOFuVSvxj_kiQ_gWVc45DilhmZZDMNgkQ,1545
54
+ slidge/slixfix/xep_0077/__init__.py,sha256=0lY1YXdgAsfrfxI_Woxaf1etHCJXe35Xtntq_icF6nA,325
55
+ slidge/slixfix/xep_0077/register.py,sha256=6nwTfHNL7Z9-1wUhpAF743TNbjQLCMP7Rflkdad8d60,10431
56
+ slidge/slixfix/xep_0077/stanza.py,sha256=Lngly7F1ChCkNKn7yl1QmN838fO-KqkAhkazxzDsz80,2410
57
+ slidge/slixfix/xep_0100/__init__.py,sha256=AtEXDQOrEWodkN3fgKR0W3Ezsz_Zza6cgO5ZaZS-JOo,107
58
+ slidge/slixfix/xep_0100/gateway.py,sha256=Fhxs2sUPnVRPa1o7RXCncnbBO2gjeZx3pbItug-8OiA,4501
59
+ slidge/slixfix/xep_0100/stanza.py,sha256=7vCzej9VFQupsTpGGl0cJWuGNH4I6oVcckBu_-fE55c,232
60
+ slidge/slixfix/xep_0153/__init__.py,sha256=wZCTLaVsXQn_wYEHA8YXdGCsspvj2rvq92iyi16W0xA,319
61
+ slidge/slixfix/xep_0153/stanza.py,sha256=qhVfxlJEKuYDuWnd_I_VT4TtJbpX2opN6kG8oxYrc3o,735
62
+ slidge/slixfix/xep_0153/vcard_avatar.py,sha256=mzaReW5c1OaeL39CeGvuzIkh3j-Z5mc2joLqn5cNc5Q,658
63
+ slidge/slixfix/xep_0264/__init__.py,sha256=c6g_y-PAwQJZ4ZLWcwXc6Q5xRPeXTvvvJH4ZKQpkj3o,109
64
+ slidge/slixfix/xep_0264/stanza.py,sha256=YvkI9rsGztkc9yOZBjf5PNKReW8aeGdF6MnrsfDckYs,864
65
+ slidge/slixfix/xep_0264/thumbnail.py,sha256=6ukgPCWJTFUnew4USB6hNtEk_ZcpWcFAvHr2r0T5znw,456
66
+ slidge/slixfix/xep_0292/__init__.py,sha256=_MvS9wGra6ig3P_dPAVlCPDJkiOFvUWGjaRsHj1woUg,98
67
+ slidge/slixfix/xep_0292/vcard4.py,sha256=V-RJy15elHraKP5oj8Rx5n-y17yJNbzI5sGwzErQvNw,3113
68
+ slidge/slixfix/xep_0313/__init__.py,sha256=rpvXxN4Fi-ey4Ww39OEAXoiaeWs3XMqvzR64hA6j_x4,368
69
+ slidge/slixfix/xep_0313/mam.py,sha256=2USgMGgklnGXPcw_1F3482HxIyd41TLx0uit43_RthA,9211
70
+ slidge/slixfix/xep_0313/stanza.py,sha256=WriAx6XKiiyZTkoTw5RHcgu3ZYdkDd6hjQ0wHqDkXE0,10249
71
+ slidge/slixfix/xep_0317/__init__.py,sha256=KRMpj3n2TYTyXzlGHdGXzNbMEvbHxn7Qd1WxqRIkrhU,104
72
+ slidge/slixfix/xep_0317/hats.py,sha256=HAZ7y5DNehpdPVpNpgo1JxnG2GVhVSElLYdARiL9KJQ,290
73
+ slidge/slixfix/xep_0317/stanza.py,sha256=HYSJSUHqPNHmrpJsschb__qazfb2Jm3WUxLsrmPqC4I,659
74
+ slidge/slixfix/xep_0356_old/__init__.py,sha256=3jGWJX2m5gWgDCxcVqCsCCVPRTcfmU96yenwvAJtOKE,180
75
+ slidge/slixfix/xep_0356_old/privilege.py,sha256=kcJzFbzhOHtQMtzOJpvvwm1pghSpealWnqhC0zc8dGo,5338
76
+ slidge/slixfix/xep_0356_old/stanza.py,sha256=i7aqcaTg6PBhVwbHToLtlrwxBj7uO-M7VrYSyElyEKI,1229
77
+ slidge/slixfix/xep_0424/__init__.py,sha256=ngz0GBepiJs_cocaohkDRTiaB8mvaEwXoqQBv9Av9o8,284
78
+ slidge/slixfix/xep_0424/retraction.py,sha256=VmJQCj4umtjslnU1ydVOL6KquZnVvqgPTAyoE1KQKwE,2448
79
+ slidge/slixfix/xep_0424/stanza.py,sha256=mT8QzRX3YcyTqTSfaaWKxyhag1s1-iQy5QW9nH6cyU8,753
80
+ slidge/slixfix/xep_0490/__init__.py,sha256=Rhu_1h1P34LfIP_yr4JQ_PBHcuNBLDzLdJMnNmNJRrE,158
81
+ slidge/slixfix/xep_0490/mds.py,sha256=KaITeEzSWgpGyU7RP-iwipjSyCEdVMPiVIT5vHVK-RM,1527
82
+ slidge/slixfix/xep_0490/stanza.py,sha256=ztec_ipyhUFz_uWQYkS0Q6LlsNiSBBC5aZK-qSmhHXk,443
83
+ slidge/util/__init__.py,sha256=BELovoTMPcPPGz3D48esBr8A4BRRHXTvavfgnArBgEc,301
84
+ slidge/util/archive_msg.py,sha256=2gq0N8GMVN8PKB0HxkWJza5FdgCDob_WPo0yVcx7DJk,1686
85
+ slidge/util/conf.py,sha256=1j2OnOsCBar1tOObErhXR5RC3Vl3faliOZ1U8J3My58,6613
86
+ slidge/util/db.py,sha256=q4IZJa2JIz_QiQHf3jU2JqZxuFjyJAXFmnUYRHR-IgU,6604
87
+ slidge/util/schema.sql,sha256=zBq4K7DbaX5cjX25JnXiEXLA9loft3mMFLJN3TGRCJE,2682
88
+ slidge/util/sql.py,sha256=xjSldsDwgpZc20cmk6UfS4nhdc7Hbuml7kjH6IZgT0I,16517
89
+ slidge/util/test.py,sha256=8cTrL-traDv2jfvfTDNgqewsBJH19ePQ1bf7qzp1RHQ,10688
90
+ slidge/util/types.py,sha256=djIOI4kBBKl_2w8gm7QLtE3NDOCA832rD_GU7A3N6U4,4689
91
+ slidge/util/util.py,sha256=t8t1nPybcitpmuSlYsOwZ8gDjfiEwTjaa4D7vtzrvQ8,8587
92
+ slidge-0.1.2.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
93
+ slidge-0.1.2.dist-info/METADATA,sha256=yEVZPfmmBIGsoFz9G6XVDjn_8l4aZjC0gNxN9f0zb1U,4736
94
+ slidge-0.1.2.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
95
+ slidge-0.1.2.dist-info/entry_points.txt,sha256=SNl72KSocF5plsu_67xyH6wVWfGTXQbzkQgXbLtzDrQ,47
96
+ slidge-0.1.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.4.0
2
+ Generator: poetry-core 1.5.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any