slidge 0.2.0b0__py3-none-any.whl → 0.2.0b1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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.0beta0"
5
+ __version__ = "0.2.0beta1"
slidge/command/adhoc.py CHANGED
@@ -9,8 +9,11 @@ from slixmpp.exceptions import XMPPError
9
9
  from slixmpp.plugins.xep_0004 import Form as SlixForm # type: ignore[attr-defined]
10
10
  from slixmpp.plugins.xep_0030.stanza.items import DiscoItems
11
11
 
12
+ from ..core import config
13
+ from ..util.util import strip_leading_emoji
12
14
  from . import Command, CommandResponseType, Confirmation, Form, TableResult
13
15
  from .base import FormField
16
+ from .categories import CommandCategory
14
17
 
15
18
  if TYPE_CHECKING:
16
19
  from ..core.gateway import BaseGateway
@@ -46,19 +49,19 @@ class AdhocProvider:
46
49
  return await self.__handle_result(session, result, adhoc_session)
47
50
 
48
51
  async def __handle_category_list(
49
- self, category: str, iq: Iq, adhoc_session: AdhocSessionType
52
+ self, category: CommandCategory, iq: Iq, adhoc_session: AdhocSessionType
50
53
  ) -> AdhocSessionType:
51
54
  try:
52
55
  session = self.xmpp.get_session_from_stanza(iq)
53
56
  except XMPPError:
54
57
  session = None
55
- commands = []
56
- for command in self._categories[category]:
58
+ commands: dict[str, Command] = {}
59
+ for command in self._categories[category.node]:
57
60
  try:
58
61
  command.raise_if_not_authorized(iq.get_from())
59
62
  except XMPPError:
60
63
  continue
61
- commands.append(command)
64
+ commands[command.NODE] = command
62
65
  if len(commands) == 0:
63
66
  raise XMPPError(
64
67
  "not-authorized", "There is no command you can run in this category"
@@ -66,7 +69,7 @@ class AdhocProvider:
66
69
  return await self.__handle_result(
67
70
  session,
68
71
  Form(
69
- category,
72
+ category.name,
70
73
  "",
71
74
  [
72
75
  FormField(
@@ -74,8 +77,11 @@ class AdhocProvider:
74
77
  label="Command",
75
78
  type="list-single",
76
79
  options=[
77
- {"label": command.NAME, "value": str(i)}
78
- for i, command in enumerate(commands)
80
+ {
81
+ "label": strip_leading_emoji_if_needed(command.NAME),
82
+ "value": command.NODE,
83
+ }
84
+ for command in commands.values()
79
85
  ],
80
86
  )
81
87
  ],
@@ -86,12 +92,12 @@ class AdhocProvider:
86
92
 
87
93
  async def __handle_category_choice(
88
94
  self,
89
- commands: list[Command],
95
+ commands: dict[str, Command],
90
96
  form_values: dict[str, str],
91
97
  session: "BaseSession[Any, Any]",
92
98
  jid: JID,
93
99
  ):
94
- command = commands[int(form_values["command"])]
100
+ command = commands[form_values["command"]]
95
101
  result = await self.__wrap_handler(command.run, session, jid)
96
102
  return result
97
103
 
@@ -207,19 +213,23 @@ class AdhocProvider:
207
213
  self.xmpp.plugin["xep_0050"].add_command( # type: ignore[no-untyped-call]
208
214
  jid=jid,
209
215
  node=command.NODE,
210
- name=command.NAME,
216
+ name=strip_leading_emoji_if_needed(command.NAME),
211
217
  handler=partial(self.__wrap_initial_handler, command),
212
218
  )
213
219
  else:
214
- if category not in self._categories:
215
- self._categories[category] = list[Command]()
220
+ if isinstance(category, str):
221
+ category = CommandCategory(category, category)
222
+ node = category.node
223
+ name = category.name
224
+ if node not in self._categories:
225
+ self._categories[node] = list[Command]()
216
226
  self.xmpp.plugin["xep_0050"].add_command( # type: ignore[no-untyped-call]
217
227
  jid=jid,
218
- node=category,
219
- name=category,
228
+ node=node,
229
+ name=strip_leading_emoji_if_needed(name),
220
230
  handler=partial(self.__handle_category_list, category),
221
231
  )
222
- self._categories[category].append(command)
232
+ self._categories[node].append(command)
223
233
 
224
234
  async def get_items(self, jid: JID, node: str, iq: Iq) -> DiscoItems:
225
235
  """
@@ -262,4 +272,10 @@ class AdhocProvider:
262
272
  return filtered_items
263
273
 
264
274
 
275
+ def strip_leading_emoji_if_needed(text: str) -> str:
276
+ if config.STRIP_LEADING_EMOJI_ADHOC:
277
+ return strip_leading_emoji(text)
278
+ return text
279
+
280
+
265
281
  log = logging.getLogger(__name__)
slidge/command/admin.py CHANGED
@@ -11,6 +11,7 @@ from slixmpp.exceptions import XMPPError
11
11
  from ..core import config
12
12
  from ..util.types import AnyBaseSession
13
13
  from .base import (
14
+ NODE_PREFIX,
14
15
  Command,
15
16
  CommandAccess,
16
17
  Confirmation,
@@ -21,6 +22,8 @@ from .base import (
21
22
  )
22
23
  from .categories import ADMINISTRATION
23
24
 
25
+ NODE_PREFIX = NODE_PREFIX + "admin/"
26
+
24
27
 
25
28
  class AdminCommand(Command):
26
29
  ACCESS = CommandAccess.ADMIN_ONLY
@@ -30,7 +33,8 @@ class AdminCommand(Command):
30
33
  class ListUsers(AdminCommand):
31
34
  NAME = "👤 List registered users"
32
35
  HELP = "List the users registered to this gateway"
33
- NODE = CHAT_COMMAND = "list_users"
36
+ CHAT_COMMAND = "list_users"
37
+ NODE = NODE_PREFIX + CHAT_COMMAND
34
38
 
35
39
  async def run(self, _session, _ifrom, *_):
36
40
  items = []
@@ -51,7 +55,8 @@ class ListUsers(AdminCommand):
51
55
  class SlidgeInfo(AdminCommand):
52
56
  NAME = "ℹ️ Server information"
53
57
  HELP = "List the users registered to this gateway"
54
- NODE = CHAT_COMMAND = "info"
58
+ CHAT_COMMAND = "info"
59
+ NODE = NODE_PREFIX + CHAT_COMMAND
55
60
  ACCESS = CommandAccess.ANY
56
61
 
57
62
  async def run(self, _session, _ifrom, *_):
@@ -105,7 +110,8 @@ class SlidgeInfo(AdminCommand):
105
110
  class DeleteUser(AdminCommand):
106
111
  NAME = "❌ Delete a user"
107
112
  HELP = "Unregister a user from the gateway"
108
- NODE = CHAT_COMMAND = "delete_user"
113
+ CHAT_COMMAND = "delete_user"
114
+ NODE = NODE_PREFIX + CHAT_COMMAND
109
115
 
110
116
  async def run(self, _session, _ifrom, *_):
111
117
  return Form(
@@ -141,7 +147,8 @@ class DeleteUser(AdminCommand):
141
147
  class ChangeLoglevel(AdminCommand):
142
148
  NAME = "📋 Change the verbosity of the logs"
143
149
  HELP = "Set the logging level"
144
- NODE = CHAT_COMMAND = "loglevel"
150
+ CHAT_COMMAND = "loglevel"
151
+ NODE = NODE_PREFIX + CHAT_COMMAND
145
152
 
146
153
  async def run(self, _session, _ifrom, *_):
147
154
  return Form(
slidge/command/base.py CHANGED
@@ -25,9 +25,12 @@ from slixmpp.types import JidStr
25
25
  from ..core import config
26
26
  from ..util.types import AnyBaseSession, FieldType
27
27
 
28
+ NODE_PREFIX = "https://slidge.im/command/core/"
29
+
28
30
  if TYPE_CHECKING:
29
31
  from ..core.gateway import BaseGateway
30
32
  from ..core.session import BaseSession
33
+ from .categories import CommandCategory
31
34
 
32
35
 
33
36
  HandlerType = Union[
@@ -178,8 +181,8 @@ class Form:
178
181
  """
179
182
  form = SlixForm() # type: ignore[no-untyped-call]
180
183
  form["type"] = "form"
181
- form["instructions"] = self.instructions
182
184
  form["title"] = self.title
185
+ form["instructions"] = self.instructions
183
186
  for fi in self.fields:
184
187
  form.append(fi.get_xml())
185
188
  return form
@@ -347,7 +350,7 @@ class Command(ABC):
347
350
  Who can use this command
348
351
  """
349
352
 
350
- CATEGORY: Optional[str] = None
353
+ CATEGORY: Optional[Union[str, "CommandCategory"]] = None
351
354
  """
352
355
  If used, the command will be under this top-level category.
353
356
  Use the same string for several commands to group them.
@@ -1,3 +1,13 @@
1
- ADMINISTRATION = "🛷️ Slidge administration"
2
- CONTACTS = "👤 Contacts"
3
- GROUPS = "👥 Groups"
1
+ from typing import NamedTuple
2
+
3
+ from .base import NODE_PREFIX
4
+
5
+
6
+ class CommandCategory(NamedTuple):
7
+ name: str
8
+ node: str
9
+
10
+
11
+ ADMINISTRATION = CommandCategory("🛷️ Slidge administration", NODE_PREFIX + "admin")
12
+ CONTACTS = CommandCategory("👤 Contacts", NODE_PREFIX + "contacts")
13
+ GROUPS = CommandCategory("👥 Groups", NODE_PREFIX + "groups")
@@ -13,6 +13,7 @@ from slixmpp.exceptions import XMPPError
13
13
  from slixmpp.types import JidStr, MessageTypes
14
14
 
15
15
  from . import Command, CommandResponseType, Confirmation, Form, TableResult
16
+ from .categories import CommandCategory
16
17
 
17
18
  if TYPE_CHECKING:
18
19
  from ..core.gateway import BaseGateway
@@ -280,7 +281,19 @@ class ChatCommandProvider:
280
281
  def _help(self, mfrom: JID):
281
282
  msg = "Available commands:"
282
283
  for c in sorted(
283
- self._commands.values(), key=lambda co: (co.CATEGORY or "", co.CHAT_COMMAND)
284
+ self._commands.values(),
285
+ key=lambda co: (
286
+ (
287
+ co.CATEGORY
288
+ if isinstance(co.CATEGORY, str)
289
+ else (
290
+ co.CATEGORY.name
291
+ if isinstance(co.CATEGORY, CommandCategory)
292
+ else ""
293
+ )
294
+ ),
295
+ co.CHAT_COMMAND,
296
+ ),
284
297
  ):
285
298
  try:
286
299
  c.raise_if_not_authorized(mfrom)
slidge/command/user.py CHANGED
@@ -26,8 +26,8 @@ if TYPE_CHECKING:
26
26
  class Search(Command):
27
27
  NAME = "🔎 Search for contacts"
28
28
  HELP = "Search for contacts via this gateway"
29
- NODE = "search"
30
29
  CHAT_COMMAND = "find"
30
+ NODE = CONTACTS.node + "/" + CHAT_COMMAND
31
31
  ACCESS = CommandAccess.USER_LOGGED
32
32
  CATEGORY = CONTACTS
33
33
 
@@ -64,7 +64,8 @@ class SyncContacts(Command):
64
64
  "Synchronize your XMPP roster with your legacy contacts. "
65
65
  "Slidge will only add/remove/modify contacts in its dedicated roster group"
66
66
  )
67
- NODE = CHAT_COMMAND = "sync-contacts"
67
+ CHAT_COMMAND = "sync-contacts"
68
+ NODE = CONTACTS.node + "/" + CHAT_COMMAND
68
69
  ACCESS = CommandAccess.USER_LOGGED
69
70
  CATEGORY = CONTACTS
70
71
 
@@ -123,7 +124,8 @@ class SyncContacts(Command):
123
124
 
124
125
  class ListContacts(Command):
125
126
  NAME = HELP = "👤 List your legacy contacts"
126
- NODE = CHAT_COMMAND = "contacts"
127
+ CHAT_COMMAND = "contacts"
128
+ NODE = CONTACTS.node + "/" + CHAT_COMMAND
127
129
  ACCESS = CommandAccess.USER_LOGGED
128
130
  CATEGORY = CONTACTS
129
131
 
@@ -143,7 +145,8 @@ class ListContacts(Command):
143
145
 
144
146
  class ListGroups(Command):
145
147
  NAME = HELP = "👥 List your legacy groups"
146
- NODE = CHAT_COMMAND = "groups"
148
+ CHAT_COMMAND = "groups"
149
+ NODE = GROUPS.node + "/" + CHAT_COMMAND
147
150
  ACCESS = CommandAccess.USER_LOGGED
148
151
  CATEGORY = GROUPS
149
152
 
@@ -162,7 +165,8 @@ class ListGroups(Command):
162
165
  class Login(Command):
163
166
  NAME = "🔐 Re-login to the legacy network"
164
167
  HELP = "Login to the legacy service"
165
- NODE = CHAT_COMMAND = "re-login"
168
+ CHAT_COMMAND = "re-login"
169
+ NODE = "https://slidge.im/command/core/" + CHAT_COMMAND
166
170
 
167
171
  ACCESS = CommandAccess.USER_NON_LOGGED
168
172
 
@@ -184,7 +188,8 @@ class Login(Command):
184
188
  class CreateGroup(Command):
185
189
  NAME = "🆕 New legacy group"
186
190
  HELP = "Create a group on the legacy service"
187
- NODE = CHAT_COMMAND = "create-group"
191
+ CHAT_COMMAND = "create-group"
192
+ NODE = GROUPS.node + "/" + CHAT_COMMAND
188
193
  CATEGORY = GROUPS
189
194
 
190
195
  ACCESS = CommandAccess.USER_LOGGED
@@ -233,7 +238,8 @@ class CreateGroup(Command):
233
238
  class Preferences(Command):
234
239
  NAME = "⚙️ Preferences"
235
240
  HELP = "Customize the gateway behaviour to your liking"
236
- NODE = CHAT_COMMAND = "preferences"
241
+ CHAT_COMMAND = "preferences"
242
+ NODE = "https://slidge.im/command/core/preferences"
237
243
  ACCESS = CommandAccess.USER
238
244
 
239
245
  async def run(
@@ -268,7 +274,8 @@ class Preferences(Command):
268
274
  class Unregister(Command):
269
275
  NAME = "❌ Unregister from the gateway"
270
276
  HELP = "Unregister from the gateway"
271
- NODE = CHAT_COMMAND = "unregister"
277
+ CHAT_COMMAND = "unregister"
278
+ NODE = "https://slidge.im/command/core/unregister"
272
279
  ACCESS = CommandAccess.USER
273
280
 
274
281
  async def run(
@@ -290,7 +297,8 @@ class Unregister(Command):
290
297
 
291
298
  class LeaveGroup(Command):
292
299
  NAME = HELP = "❌ Leave a legacy group"
293
- NODE = CHAT_COMMAND = "leave-group"
300
+ CHAT_COMMAND = "leave-group"
301
+ NODE = GROUPS.node + "/" + CHAT_COMMAND
294
302
  ACCESS = CommandAccess.USER_LOGGED
295
303
  CATEGORY = GROUPS
296
304
 
slidge/core/config.py CHANGED
@@ -214,3 +214,9 @@ DEV_MODE__DOC = (
214
214
  "Enables an interactive python shell via chat commands, for admins."
215
215
  "Not safe to use in prod, but great during dev."
216
216
  )
217
+
218
+ STRIP_LEADING_EMOJI_ADHOC = False
219
+ STRIP_LEADING_EMOJI_ADHOC__DOC = (
220
+ "Strip the leading emoji in ad-hoc command names, if present, in case you "
221
+ "are a emoji-hater."
222
+ )
@@ -59,6 +59,8 @@ room_table = sa.Table(
59
59
 
60
60
 
61
61
  def upgrade() -> None:
62
+ if op.get_bind().engine.name == "postgresql":
63
+ return
62
64
  with op.batch_alter_table(
63
65
  "room",
64
66
  schema=None,
@@ -37,7 +37,7 @@ def upgrade() -> None:
37
37
  native_enum=False,
38
38
  ),
39
39
  nullable=False,
40
- server_default=sa.text("pc"),
40
+ server_default=sa.literal("pc"),
41
41
  )
42
42
  )
43
43
 
@@ -95,6 +95,12 @@ def upgrade() -> None:
95
95
  op.add_column("room", sa.Column("description", sa.String(), nullable=True))
96
96
  op.add_column("room", sa.Column("subject", sa.String(), nullable=True))
97
97
  op.add_column("room", sa.Column("subject_date", sa.DateTime(), nullable=True))
98
+
99
+ if op.get_bind().engine.name == "postgresql":
100
+ op.execute(
101
+ "CREATE TYPE muctype AS ENUM ('GROUP', 'CHANNEL', 'CHANNEL_NON_ANONYMOUS')"
102
+ )
103
+
98
104
  op.add_column(
99
105
  "room",
100
106
  sa.Column(
@@ -37,12 +37,13 @@ def upgrade() -> None:
37
37
 
38
38
  with op.batch_alter_table("room", schema=None) as batch_op:
39
39
  batch_op.add_column(sa.Column("avatar_legacy_id", sa.String(), nullable=True))
40
- batch_op.create_unique_constraint(
41
- "uq_room_user_account_id_jid", ["user_account_id", "jid"]
42
- )
43
- batch_op.create_unique_constraint(
44
- "uq_room_user_account_id_legacy_id", ["user_account_id", "legacy_id"]
45
- )
40
+ if op.get_bind().engine.name != "postgresql":
41
+ batch_op.create_unique_constraint(
42
+ "uq_room_user_account_id_jid", ["user_account_id", "jid"]
43
+ )
44
+ batch_op.create_unique_constraint(
45
+ "uq_room_user_account_id_legacy_id", ["user_account_id", "legacy_id"]
46
+ )
46
47
 
47
48
  for room_pk, avatar_legacy_id in room_avatars:
48
49
  conn.execute(
@@ -24,6 +24,10 @@ def upgrade() -> None:
24
24
  # since we don't want source to be nullable, we drop all rows first.
25
25
  # This is what you get by using alpha versions!
26
26
  op.execute(sa.delete(ArchivedMessage))
27
+
28
+ if op.get_bind().engine.name == "postgresql":
29
+ op.execute("CREATE TYPE archivedmessagesource AS ENUM ('LIVE', 'BACKFILL')")
30
+
27
31
  # ### commands auto generated by Alembic - please adjust! ###
28
32
 
29
33
  with op.batch_alter_table("mam", schema=None) as batch_op:
slidge/db/models.py CHANGED
@@ -317,7 +317,7 @@ class LegacyIdsMulti(Base):
317
317
 
318
318
  legacy_id: Mapped[str] = mapped_column(nullable=False)
319
319
  xmpp_ids: Mapped[list["XmppIdsMulti"]] = relationship(
320
- back_populates="legacy_ids_multi"
320
+ back_populates="legacy_ids_multi", cascade="all, delete-orphan"
321
321
  )
322
322
 
323
323
 
slidge/db/store.py CHANGED
@@ -1001,9 +1001,9 @@ class ParticipantStore(EngineMixin):
1001
1001
  def __init__(self, *a, **kw):
1002
1002
  super().__init__(*a, **kw)
1003
1003
  with self.session() as session:
1004
- session.execute(delete(Participant))
1005
- session.execute(delete(Hat))
1006
1004
  session.execute(delete(participant_hats))
1005
+ session.execute(delete(Hat))
1006
+ session.execute(delete(Participant))
1007
1007
  session.commit()
1008
1008
 
1009
1009
  def add(self, room_pk: int, nickname: str) -> int:
slidge/util/util.py CHANGED
@@ -9,6 +9,13 @@ from pathlib import Path
9
9
  from time import time
10
10
  from typing import TYPE_CHECKING, Callable, NamedTuple, Optional, Type, TypeVar
11
11
 
12
+ try:
13
+ import emoji
14
+ except ImportError:
15
+ EMOJI_LIB_AVAILABLE = False
16
+ else:
17
+ EMOJI_LIB_AVAILABLE = True
18
+
12
19
  from .types import Mention, ResourceDict
13
20
 
14
21
  if TYPE_CHECKING:
@@ -318,3 +325,14 @@ def timeit(func):
318
325
  return r
319
326
 
320
327
  return wrapped
328
+
329
+
330
+ def strip_leading_emoji(text: str) -> str:
331
+ if not EMOJI_LIB_AVAILABLE:
332
+ return text
333
+ words = text.split(" ")
334
+ # is_emoji returns False for 🛷️ for obscure reasons,
335
+ # purely_emoji seems better
336
+ if len(words) > 1 and emoji.purely_emoji(words[0]):
337
+ return " ".join(words[1:])
338
+ return text
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: slidge
3
- Version: 0.2.0b0
3
+ Version: 0.2.0b1
4
4
  Summary: XMPP bridging framework
5
5
  Home-page: https://sr.ht/~nicoco/slidge/
6
6
  License: AGPL-3.0-or-later
@@ -1,19 +1,19 @@
1
1
  slidge/__init__.py,sha256=S0tUjqpZlzsr8G4Y_1Xt-KCYB07qaknTB0OwHU8k29U,1587
2
2
  slidge/__main__.py,sha256=ydjUklOoavS4YlGfjRX_8BQN2DaSbaXPMi47RkOgcFI,37
3
- slidge/__version__.py,sha256=9HCdKNn7jsnGlM4hiADRgDmlQEfeHOYi3XRNJ7Fe-2w,169
3
+ slidge/__version__.py,sha256=o9z5MY6bh2r2Gr5POdoOH_xk8Y3xIorqS2ZH6xZtwD4,169
4
4
  slidge/command/__init__.py,sha256=UYf1mjCYbZ5G7PIgaFTWSQRAzEJkQ6dTH8Fu_e_XnO0,613
5
- slidge/command/adhoc.py,sha256=9PsTsGMPKAK_YXQpwdcH9SSDki8YQ49OZ5p65W5HA6k,9412
6
- slidge/command/admin.py,sha256=x_kJ0TJhzf6d3OBIOXFjudZFO8bRYUG919td7OjMCug,6008
7
- slidge/command/base.py,sha256=7NSzPZdBLZElrm3smzvFKgP0GUggxXdkhclxIKCjtT8,13036
8
- slidge/command/categories.py,sha256=BJCfaga2qoAxnHfgHD7I_RKZuBA5nnNOukkWHJwsUFE,99
9
- slidge/command/chat_command.py,sha256=VBs6IuDka1IyyMzz0ZyE9zMImaEzUZLcnffxq_vwb4M,10565
5
+ slidge/command/adhoc.py,sha256=-AO4h1N6owSuuqZon5tDL29O6qmEeAd1pcPjGCkzKRs,10065
6
+ slidge/command/admin.py,sha256=TYrzgCIhjcTIwl1IUaFlUd3D98SPyao10gB20zo8b3Q,6187
7
+ slidge/command/base.py,sha256=S_bKUJB0fnKs58PvjgFf15_6cw-8k2bMeSECTmFxQGQ,13155
8
+ slidge/command/categories.py,sha256=vF0KGDV9sEn8TNkcMoDRw-u3gEyNHSXghOU2JRHQtKs,351
9
+ slidge/command/chat_command.py,sha256=8_1mqXNLlcwzozbNhZAAYwxavG09rNR_o9G3TwY-lO8,10941
10
10
  slidge/command/register.py,sha256=fzPcGUoJtainnDOiC13gWV-uYLuJcsmdKGJ-jXT1qIo,6697
11
- slidge/command/user.py,sha256=P4mU1wn1ywtquo0KKQsWddOhIKMV4HOueZAXOgmVvek,11700
11
+ slidge/command/user.py,sha256=0pt9k41npv7MRI_0vauuR1JPb7Gf7UE2lOQeL2XNd7U,12065
12
12
  slidge/contact/__init__.py,sha256=WMMaHk7UW7YT9EH2LtPdkU0bHQaOp4ikBhbBQskmoc8,191
13
13
  slidge/contact/contact.py,sha256=kKtJ9NPLS9DPVyyahx_K-Mtp5k5UQdQJZavC1XCmWlc,23104
14
14
  slidge/contact/roster.py,sha256=-Ei0f0cXX1LFpY29u4Ik68ikno3m2WRA5n5l8Nbjd_E,10267
15
15
  slidge/core/__init__.py,sha256=RG7Jj5JCJERjhqJ31lOLYV-7bH_oblClQD1KF9LsTXo,68
16
- slidge/core/config.py,sha256=voRFIlVDtKTZCdjc-zbwgnngFZrGvJjJ1dxRZm0BJK0,7514
16
+ slidge/core/config.py,sha256=WP3-ScXqdAhJBX7IRB5pBi_tAV_vE6G5W3Z-LGGULQw,7691
17
17
  slidge/core/dispatcher/__init__.py,sha256=1EXcjXietUKlxEqdrCWCV3xZ3q_DSsjHoqWrPMbtYao,84
18
18
  slidge/core/dispatcher/caps.py,sha256=vzCAXo_bhALuLEpJWtyJTzVfWx96g1AsWD8_wkoDl0Y,2028
19
19
  slidge/core/dispatcher/disco.py,sha256=j56VY9NIFzwPEWFKQQZ7YIqS9GdD-ZaF_K8a2L-JvRk,2006
@@ -54,26 +54,26 @@ slidge/db/alembic/env.py,sha256=hsBlRNs0zF5diSHGRSa8Fi3qRVQDA2rJdR41AEIdvxc,1642
54
54
  slidge/db/alembic/old_user_store.py,sha256=zFOv0JEWQQK0_TMRlU4Z0G5Mc9pxvEErLyOzXmRAe5Q,5209
55
55
  slidge/db/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
56
56
  slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py,sha256=mUL-0Io6ZPd_QbnKfwGYyjdMcM2uxQ0Wg72H23-2t_E,1033
57
- slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py,sha256=bc_H_tPCVjiiUDqWE3oQtnIvsv2tlrzt0NB2f24mbdk,2862
57
+ slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py,sha256=kzHuHGhzey5CY0p_OsKf5a-3zSk2649wqg2ToLiSD1I,2927
58
58
  slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py,sha256=CLB-kOP9Rc0FJIKDLef912L5sYkjpTIPC8fhrIdrC7k,1084
59
59
  slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py,sha256=f8TFS28CXjGhvIn41UYMoHYeODfqhKfo4O7gk-JwA1E,1134
60
60
  slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py,sha256=CMVP2wFz6s7t57eWdSaGtck8BXzfVPJhHE5AoWi34tI,1359
61
- slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py,sha256=O5BY1vpbtuYT5j6i3EMuuJAf6loIYT1kco8c-c6TF5g,1391
61
+ slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py,sha256=jCdwCOnX9VDgnqIFFHGKaPA7w87Hm9nvR1rMY0LrA30,1394
62
62
  slidge/db/alembic/versions/45c24cc73c91_add_bob.py,sha256=UjMySZ5LaInyPt0KbAxx0rF4GQhZh8CwBeqHtNPdG1c,1249
63
63
  slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py,sha256=m3USa76h0O2Xut-NePXIOZfkXl0bx0d5FyjOYpd34Jo,1977
64
64
  slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py,sha256=g37po0ydp8ZmzJrE5oFV7GscnploxjCtPDpw28SqVGk,1429
65
65
  slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py,sha256=18tG8B03Kq8Qz_-mMd28Beed6jow8XNTtrz7gT5QY3g,1210
66
- slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py,sha256=olXaOEEsUSasqaaKdlP1cBODsMhmV1i90qbpDM2vTm4,4696
66
+ slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py,sha256=ikoAlRV3_BJcDcFRANF-9HTB--0xpY0C5XdGuMuW9c0,4866
67
67
  slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py,sha256=XFHaHjPMoxKxKRjNBnYHBzMtS6K38ENcsGzgzlyp60g,2649
68
- slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py,sha256=tLnVrbtWzxSPXACIhWPeLxxCIFdnVxK-izoNZxbvA3A,2701
68
+ slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py,sha256=VprqEVHipYuM-ea-CIM4_ubOD5zJ9inLTbhXc869n3A,2779
69
69
  slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py,sha256=2tiRxoC9PYOQn6XQrwK0JTEsb45Pzp2PsKoZSS4rcIA,7564
70
- slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py,sha256=N6HYpFBhMckAFLZFW8PY8Us1qzXlauEQiDwEYwd9_K8,1422
70
+ slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py,sha256=r2sOgR5HcfueJyc3cWNDRmlZzdHOSX6nl2gef54wDbk,1559
71
71
  slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py,sha256=jjQmlRv6nqdm5q6LbwVpSUSkTBj1c76Hiq8e8q77q3g,933
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=mazginFllRNsC2w-SW_Y9HUMtruYnzSDCGGjsJwwsp8,13782
76
- slidge/db/store.py,sha256=7-HIml_wmgwwKe1AxI9yXbtWGz7yxH0cMc_IY4p1Wl4,46696
75
+ slidge/db/models.py,sha256=ZbnoUK2yajUJXzyCAWlkTQtkuJAaH1gc9G0ilRpfADg,13812
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
@@ -123,9 +123,9 @@ slidge/util/conf.py,sha256=1j2OnOsCBar1tOObErhXR5RC3Vl3faliOZ1U8J3My58,6613
123
123
  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
- slidge/util/util.py,sha256=DyJWO2pmE-RiB9Rsy6TUTcvB-BDlmLZBW4PELx4arFQ,9156
127
- slidge-0.2.0b0.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
128
- slidge-0.2.0b0.dist-info/METADATA,sha256=JrkUpw6lNEWr3ESfNKv-NMuvLPIwqz-3G2Gt7i9nkkk,5005
129
- slidge-0.2.0b0.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
130
- slidge-0.2.0b0.dist-info/entry_points.txt,sha256=btz6mbzx1X6fjFWAS_Bo5qNi8PtxUsDgunt-6r4JDHw,43
131
- slidge-0.2.0b0.dist-info/RECORD,,
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,,