slidge 0.2.11__py3-none-any.whl → 0.3.0__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.
Files changed (93) hide show
  1. slidge/__init__.py +5 -2
  2. slidge/command/adhoc.py +9 -3
  3. slidge/command/admin.py +16 -12
  4. slidge/command/base.py +16 -12
  5. slidge/command/chat_command.py +25 -16
  6. slidge/command/user.py +7 -8
  7. slidge/contact/contact.py +123 -210
  8. slidge/contact/roster.py +108 -105
  9. slidge/core/config.py +2 -43
  10. slidge/core/dispatcher/caps.py +9 -2
  11. slidge/core/dispatcher/disco.py +13 -3
  12. slidge/core/dispatcher/message/__init__.py +1 -1
  13. slidge/core/dispatcher/message/chat_state.py +17 -8
  14. slidge/core/dispatcher/message/marker.py +7 -5
  15. slidge/core/dispatcher/message/message.py +120 -93
  16. slidge/core/dispatcher/muc/__init__.py +1 -1
  17. slidge/core/dispatcher/muc/admin.py +4 -4
  18. slidge/core/dispatcher/muc/mam.py +10 -6
  19. slidge/core/dispatcher/muc/misc.py +4 -2
  20. slidge/core/dispatcher/muc/owner.py +5 -3
  21. slidge/core/dispatcher/muc/ping.py +3 -1
  22. slidge/core/dispatcher/presence.py +26 -15
  23. slidge/core/dispatcher/registration.py +20 -12
  24. slidge/core/dispatcher/search.py +7 -3
  25. slidge/core/dispatcher/session_dispatcher.py +13 -5
  26. slidge/core/dispatcher/util.py +37 -27
  27. slidge/core/dispatcher/vcard.py +7 -4
  28. slidge/core/gateway.py +177 -87
  29. slidge/core/mixins/__init__.py +1 -11
  30. slidge/core/mixins/attachment.py +200 -147
  31. slidge/core/mixins/avatar.py +105 -177
  32. slidge/core/mixins/base.py +3 -1
  33. slidge/core/mixins/db.py +50 -2
  34. slidge/core/mixins/disco.py +1 -1
  35. slidge/core/mixins/message.py +19 -17
  36. slidge/core/mixins/message_maker.py +29 -15
  37. slidge/core/mixins/message_text.py +67 -30
  38. slidge/core/mixins/presence.py +94 -37
  39. slidge/core/pubsub.py +42 -47
  40. slidge/core/session.py +95 -60
  41. slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +361 -0
  42. slidge/db/avatar.py +150 -119
  43. slidge/db/meta.py +33 -22
  44. slidge/db/models.py +69 -117
  45. slidge/db/store.py +414 -1094
  46. slidge/group/archive.py +65 -55
  47. slidge/group/bookmarks.py +96 -59
  48. slidge/group/participant.py +150 -144
  49. slidge/group/room.py +351 -328
  50. slidge/main.py +34 -22
  51. slidge/migration.py +17 -29
  52. slidge/slixfix/__init__.py +20 -4
  53. slidge/slixfix/delivery_receipt.py +6 -4
  54. slidge/slixfix/link_preview/link_preview.py +1 -1
  55. slidge/slixfix/link_preview/stanza.py +1 -1
  56. slidge/slixfix/roster.py +5 -7
  57. slidge/slixfix/xep_0077/register.py +8 -8
  58. slidge/slixfix/xep_0077/stanza.py +7 -7
  59. slidge/slixfix/xep_0100/gateway.py +12 -13
  60. slidge/slixfix/xep_0153/vcard_avatar.py +1 -1
  61. slidge/slixfix/xep_0292/vcard4.py +12 -2
  62. slidge/util/archive_msg.py +11 -5
  63. slidge/util/conf.py +27 -21
  64. slidge/util/jid_escaping.py +1 -1
  65. slidge/{core/mixins → util}/lock.py +6 -6
  66. slidge/util/test.py +30 -29
  67. slidge/util/types.py +24 -18
  68. slidge/util/util.py +26 -22
  69. {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/METADATA +1 -1
  70. slidge-0.3.0.dist-info/RECORD +95 -0
  71. {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/WHEEL +1 -1
  72. slidge/db/alembic/versions/04cf35e3cf85_add_participant_nickname_no_illegal.py +0 -33
  73. slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +0 -36
  74. slidge/db/alembic/versions/15b0bd83407a_remove_bogus_unique_constraints_on_room_.py +0 -85
  75. slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +0 -36
  76. slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +0 -37
  77. slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +0 -41
  78. slidge/db/alembic/versions/3071e0fa69d4_add_contact_client_type.py +0 -52
  79. slidge/db/alembic/versions/45c24cc73c91_add_bob.py +0 -42
  80. slidge/db/alembic/versions/5bd48bfdffa2_lift_room_legacy_id_constraint.py +0 -61
  81. slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +0 -48
  82. slidge/db/alembic/versions/8b993243a536_add_vcard_content_to_contact_table.py +0 -43
  83. slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +0 -139
  84. slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +0 -50
  85. slidge/db/alembic/versions/abba1ae0edb3_store_avatar_legacy_id_in_the_contact_.py +0 -79
  86. slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +0 -214
  87. slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +0 -52
  88. slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +0 -34
  89. slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +0 -26
  90. slidge-0.2.11.dist-info/RECORD +0 -112
  91. {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/entry_points.txt +0 -0
  92. {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/licenses/LICENSE +0 -0
  93. {slidge-0.2.11.dist-info → slidge-0.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,361 @@
1
+ """Initial schema
2
+
3
+ Revision ID: cef02a8b1451
4
+ Revises:
5
+ Create Date: 2025-08-28 12:48:16.890606
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ import slidge
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "cef02a8b1451"
18
+ down_revision: Union[str, None] = None
19
+ branch_labels: Union[str, Sequence[str], None] = None
20
+ depends_on: Union[str, Sequence[str], None] = None
21
+
22
+
23
+ def upgrade() -> None:
24
+ # ### commands auto generated by Alembic - please adjust! ###
25
+ op.create_table(
26
+ "avatar",
27
+ sa.Column("id", sa.Integer(), nullable=False),
28
+ sa.Column("hash", sa.String(), nullable=False),
29
+ sa.Column("height", sa.Integer(), nullable=False),
30
+ sa.Column("width", sa.Integer(), nullable=False),
31
+ sa.Column("legacy_id", sa.String(), nullable=True),
32
+ sa.Column("url", sa.String(), nullable=True),
33
+ sa.Column("etag", sa.String(), nullable=True),
34
+ sa.Column("last_modified", sa.String(), nullable=True),
35
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_avatar")),
36
+ sa.UniqueConstraint("hash", name=op.f("uq_avatar_hash")),
37
+ sa.UniqueConstraint("legacy_id", name=op.f("uq_avatar_legacy_id")),
38
+ )
39
+ op.create_table(
40
+ "bob",
41
+ sa.Column("id", sa.Integer(), nullable=False),
42
+ sa.Column("file_name", sa.String(), nullable=False),
43
+ sa.Column("sha_1", sa.String(), nullable=False),
44
+ sa.Column("sha_256", sa.String(), nullable=False),
45
+ sa.Column("sha_512", sa.String(), nullable=False),
46
+ sa.Column("content_type", sa.String(), nullable=False),
47
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_bob")),
48
+ sa.UniqueConstraint("sha_1", name=op.f("uq_bob_sha_1")),
49
+ sa.UniqueConstraint("sha_256", name=op.f("uq_bob_sha_256")),
50
+ sa.UniqueConstraint("sha_512", name=op.f("uq_bob_sha_512")),
51
+ )
52
+ op.create_table(
53
+ "user_account",
54
+ sa.Column("id", sa.Integer(), nullable=False),
55
+ sa.Column("jid", slidge.db.meta.JIDType(), nullable=False),
56
+ sa.Column(
57
+ "registration_date",
58
+ sa.DateTime(),
59
+ server_default=sa.text("(CURRENT_TIMESTAMP)"),
60
+ nullable=False,
61
+ ),
62
+ sa.Column(
63
+ "legacy_module_data", slidge.db.meta.JSONEncodedDict(), nullable=False
64
+ ),
65
+ sa.Column("preferences", slidge.db.meta.JSONEncodedDict(), nullable=False),
66
+ sa.Column("avatar_hash", sa.String(), nullable=True),
67
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_user_account")),
68
+ sa.UniqueConstraint("jid", name=op.f("uq_user_account_jid")),
69
+ )
70
+ op.create_table(
71
+ "attachment",
72
+ sa.Column("id", sa.Integer(), nullable=False),
73
+ sa.Column("user_account_id", sa.Integer(), nullable=False),
74
+ sa.Column("legacy_file_id", sa.String(), nullable=True),
75
+ sa.Column("url", sa.String(), nullable=False),
76
+ sa.Column("sims", sa.String(), nullable=True),
77
+ sa.Column("sfs", sa.String(), nullable=True),
78
+ sa.ForeignKeyConstraint(
79
+ ["user_account_id"],
80
+ ["user_account.id"],
81
+ name=op.f("fk_attachment_user_account_id_user_account"),
82
+ ),
83
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_attachment")),
84
+ sa.UniqueConstraint(
85
+ "user_account_id",
86
+ "legacy_file_id",
87
+ name=op.f("uq_attachment_user_account_id"),
88
+ ),
89
+ )
90
+ with op.batch_alter_table("attachment", schema=None) as batch_op:
91
+ batch_op.create_index(
92
+ batch_op.f("ix_attachment_legacy_file_id"), ["legacy_file_id"], unique=False
93
+ )
94
+ batch_op.create_index(batch_op.f("ix_attachment_url"), ["url"], unique=False)
95
+
96
+ op.create_table(
97
+ "contact",
98
+ sa.Column("id", sa.Integer(), nullable=False),
99
+ sa.Column("user_account_id", sa.Integer(), nullable=False),
100
+ sa.Column("legacy_id", sa.String(), nullable=False),
101
+ sa.Column("jid", slidge.db.meta.JIDType(), nullable=False),
102
+ sa.Column("avatar_id", sa.Integer(), nullable=True),
103
+ sa.Column("nick", sa.String(), nullable=True),
104
+ sa.Column("cached_presence", sa.Boolean(), nullable=False),
105
+ sa.Column("last_seen", sa.DateTime(), nullable=True),
106
+ sa.Column("ptype", sa.String(), nullable=True),
107
+ sa.Column("pstatus", sa.String(), nullable=True),
108
+ sa.Column("pshow", sa.String(), nullable=True),
109
+ sa.Column("caps_ver", sa.String(), nullable=True),
110
+ sa.Column("is_friend", sa.Boolean(), nullable=False),
111
+ sa.Column("added_to_roster", sa.Boolean(), nullable=False),
112
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
113
+ sa.Column("updated", sa.Boolean(), nullable=False),
114
+ sa.Column("vcard", sa.String(), nullable=True),
115
+ sa.Column("vcard_fetched", sa.Boolean(), nullable=False),
116
+ sa.Column(
117
+ "client_type",
118
+ sa.Enum(
119
+ "bot",
120
+ "console",
121
+ "game",
122
+ "handheld",
123
+ "pc",
124
+ "phone",
125
+ "sms",
126
+ "tablet",
127
+ "web",
128
+ native_enum=False,
129
+ ),
130
+ nullable=False,
131
+ ),
132
+ sa.ForeignKeyConstraint(
133
+ ["avatar_id"], ["avatar.id"], name=op.f("fk_contact_avatar_id_avatar")
134
+ ),
135
+ sa.ForeignKeyConstraint(
136
+ ["user_account_id"],
137
+ ["user_account.id"],
138
+ name=op.f("fk_contact_user_account_id_user_account"),
139
+ ),
140
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_contact")),
141
+ sa.UniqueConstraint(
142
+ "user_account_id", "jid", name=op.f("uq_contact_user_account_id")
143
+ ),
144
+ sa.UniqueConstraint(
145
+ "user_account_id", "legacy_id", name=op.f("uq_contact_user_account_id")
146
+ ),
147
+ )
148
+ op.create_table(
149
+ "room",
150
+ sa.Column("id", sa.Integer(), nullable=False),
151
+ sa.Column("user_account_id", sa.Integer(), nullable=False),
152
+ sa.Column("legacy_id", sa.String(), nullable=False),
153
+ sa.Column("jid", slidge.db.meta.JIDType(), nullable=False),
154
+ sa.Column("avatar_id", sa.Integer(), nullable=True),
155
+ sa.Column("name", sa.String(), nullable=True),
156
+ sa.Column("description", sa.String(), nullable=True),
157
+ sa.Column("subject", sa.String(), nullable=True),
158
+ sa.Column("subject_date", sa.DateTime(), nullable=True),
159
+ sa.Column("subject_setter", sa.String(), nullable=True),
160
+ sa.Column("n_participants", sa.Integer(), nullable=True),
161
+ sa.Column(
162
+ "muc_type",
163
+ sa.Enum("GROUP", "CHANNEL", "CHANNEL_NON_ANONYMOUS", name="muctype"),
164
+ nullable=False,
165
+ ),
166
+ sa.Column("user_nick", sa.String(), nullable=True),
167
+ sa.Column("user_resources", sa.String(), nullable=True),
168
+ sa.Column("participants_filled", sa.Boolean(), nullable=False),
169
+ sa.Column("history_filled", sa.Boolean(), nullable=False),
170
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
171
+ sa.Column("updated", sa.Boolean(), nullable=False),
172
+ sa.ForeignKeyConstraint(
173
+ ["avatar_id"], ["avatar.id"], name=op.f("fk_room_avatar_id_avatar")
174
+ ),
175
+ sa.ForeignKeyConstraint(
176
+ ["user_account_id"],
177
+ ["user_account.id"],
178
+ name=op.f("fk_room_user_account_id_user_account"),
179
+ ),
180
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_room")),
181
+ sa.UniqueConstraint(
182
+ "user_account_id", "jid", name="uq_room_user_account_id_jid"
183
+ ),
184
+ sa.UniqueConstraint(
185
+ "user_account_id", "legacy_id", name="uq_room_user_account_id_legacy_id"
186
+ ),
187
+ )
188
+ op.create_table(
189
+ "contact_sent",
190
+ sa.Column("id", sa.Integer(), nullable=False),
191
+ sa.Column("contact_id", sa.Integer(), nullable=False),
192
+ sa.Column("msg_id", sa.String(), nullable=False),
193
+ sa.ForeignKeyConstraint(
194
+ ["contact_id"],
195
+ ["contact.id"],
196
+ name=op.f("fk_contact_sent_contact_id_contact"),
197
+ ),
198
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_contact_sent")),
199
+ sa.UniqueConstraint(
200
+ "contact_id", "msg_id", name=op.f("uq_contact_sent_contact_id")
201
+ ),
202
+ )
203
+ op.create_table(
204
+ "direct_msg",
205
+ sa.Column("foreign_key", sa.Integer(), nullable=False),
206
+ sa.Column("id", sa.Integer(), nullable=False),
207
+ sa.Column("legacy_id", sa.String(), nullable=False),
208
+ sa.Column("xmpp_id", sa.String(), nullable=False),
209
+ sa.ForeignKeyConstraint(
210
+ ["foreign_key"],
211
+ ["contact.id"],
212
+ name=op.f("fk_direct_msg_foreign_key_contact"),
213
+ ),
214
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_direct_msg")),
215
+ )
216
+ with op.batch_alter_table("direct_msg", schema=None) as batch_op:
217
+ batch_op.create_index(
218
+ "ix_direct_msg_legacy_id", ["legacy_id", "foreign_key"], unique=False
219
+ )
220
+
221
+ op.create_table(
222
+ "direct_thread",
223
+ sa.Column("foreign_key", sa.Integer(), nullable=False),
224
+ sa.Column("id", sa.Integer(), nullable=False),
225
+ sa.Column("legacy_id", sa.String(), nullable=False),
226
+ sa.Column("xmpp_id", sa.String(), nullable=False),
227
+ sa.ForeignKeyConstraint(
228
+ ["foreign_key"],
229
+ ["contact.id"],
230
+ name=op.f("fk_direct_thread_foreign_key_contact"),
231
+ ),
232
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_direct_thread")),
233
+ )
234
+ with op.batch_alter_table("direct_thread", schema=None) as batch_op:
235
+ batch_op.create_index(
236
+ "ix_direct_direct_thread_id", ["legacy_id", "foreign_key"], unique=False
237
+ )
238
+
239
+ op.create_table(
240
+ "group_msg",
241
+ sa.Column("foreign_key", sa.Integer(), nullable=False),
242
+ sa.Column("id", sa.Integer(), nullable=False),
243
+ sa.Column("legacy_id", sa.String(), nullable=False),
244
+ sa.Column("xmpp_id", sa.String(), nullable=False),
245
+ sa.ForeignKeyConstraint(
246
+ ["foreign_key"], ["room.id"], name=op.f("fk_group_msg_foreign_key_room")
247
+ ),
248
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_group_msg")),
249
+ )
250
+ with op.batch_alter_table("group_msg", schema=None) as batch_op:
251
+ batch_op.create_index(
252
+ "ix_group_msg_legacy_id", ["legacy_id", "foreign_key"], unique=False
253
+ )
254
+
255
+ op.create_table(
256
+ "group_thread",
257
+ sa.Column("foreign_key", sa.Integer(), nullable=False),
258
+ sa.Column("id", sa.Integer(), nullable=False),
259
+ sa.Column("legacy_id", sa.String(), nullable=False),
260
+ sa.Column("xmpp_id", sa.String(), nullable=False),
261
+ sa.ForeignKeyConstraint(
262
+ ["foreign_key"], ["room.id"], name=op.f("fk_group_thread_foreign_key_room")
263
+ ),
264
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_group_thread")),
265
+ )
266
+ with op.batch_alter_table("group_thread", schema=None) as batch_op:
267
+ batch_op.create_index(
268
+ "ix_direct_group_thread_id", ["legacy_id", "foreign_key"], unique=False
269
+ )
270
+
271
+ op.create_table(
272
+ "mam",
273
+ sa.Column("id", sa.Integer(), nullable=False),
274
+ sa.Column("room_id", sa.Integer(), nullable=False),
275
+ sa.Column("stanza_id", sa.String(), nullable=False),
276
+ sa.Column("timestamp", sa.DateTime(), nullable=False),
277
+ sa.Column("author_jid", slidge.db.meta.JIDType(), nullable=False),
278
+ sa.Column(
279
+ "source",
280
+ sa.Enum("LIVE", "BACKFILL", name="archivedmessagesource"),
281
+ nullable=False,
282
+ ),
283
+ sa.Column("legacy_id", sa.String(), nullable=True),
284
+ sa.Column("stanza", sa.String(), nullable=False),
285
+ sa.ForeignKeyConstraint(
286
+ ["room_id"], ["room.id"], name=op.f("fk_mam_room_id_room")
287
+ ),
288
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_mam")),
289
+ sa.UniqueConstraint("room_id", "stanza_id", name=op.f("uq_mam_room_id")),
290
+ )
291
+ op.create_table(
292
+ "participant",
293
+ sa.Column("id", sa.Integer(), nullable=False),
294
+ sa.Column("room_id", sa.Integer(), nullable=False),
295
+ sa.Column("contact_id", sa.Integer(), nullable=True),
296
+ sa.Column("is_user", sa.Boolean(), nullable=False),
297
+ sa.Column(
298
+ "affiliation",
299
+ sa.Enum("outcast", "member", "admin", "owner", "none", native_enum=False),
300
+ nullable=False,
301
+ ),
302
+ sa.Column(
303
+ "role",
304
+ sa.Enum("moderator", "participant", "visitor", "none", native_enum=False),
305
+ nullable=False,
306
+ ),
307
+ sa.Column("presence_sent", sa.Boolean(), nullable=False),
308
+ sa.Column("resource", sa.String(), nullable=False),
309
+ sa.Column("nickname", sa.String(), nullable=False),
310
+ sa.Column("nickname_no_illegal", sa.String(), nullable=False),
311
+ sa.Column("hats", sa.JSON(), nullable=False),
312
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
313
+ sa.ForeignKeyConstraint(
314
+ ["contact_id"],
315
+ ["contact.id"],
316
+ name=op.f("fk_participant_contact_id_contact"),
317
+ ),
318
+ sa.ForeignKeyConstraint(
319
+ ["room_id"], ["room.id"], name=op.f("fk_participant_room_id_room")
320
+ ),
321
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_participant")),
322
+ sa.UniqueConstraint(
323
+ "room_id", "contact_id", name=op.f("uq_participant_room_id")
324
+ ),
325
+ sa.UniqueConstraint("room_id", "resource", name=op.f("uq_participant_room_id")),
326
+ )
327
+ # ### end Alembic commands ###
328
+
329
+
330
+ def downgrade() -> None:
331
+ # ### commands auto generated by Alembic - please adjust! ###
332
+ op.drop_table("participant")
333
+ op.drop_table("mam")
334
+ with op.batch_alter_table("group_thread", schema=None) as batch_op:
335
+ batch_op.drop_index("ix_direct_group_thread_id")
336
+
337
+ op.drop_table("group_thread")
338
+ with op.batch_alter_table("group_msg", schema=None) as batch_op:
339
+ batch_op.drop_index("ix_group_msg_legacy_id")
340
+
341
+ op.drop_table("group_msg")
342
+ with op.batch_alter_table("direct_thread", schema=None) as batch_op:
343
+ batch_op.drop_index("ix_direct_direct_thread_id")
344
+
345
+ op.drop_table("direct_thread")
346
+ with op.batch_alter_table("direct_msg", schema=None) as batch_op:
347
+ batch_op.drop_index("ix_direct_msg_legacy_id")
348
+
349
+ op.drop_table("direct_msg")
350
+ op.drop_table("contact_sent")
351
+ op.drop_table("room")
352
+ op.drop_table("contact")
353
+ with op.batch_alter_table("attachment", schema=None) as batch_op:
354
+ batch_op.drop_index(batch_op.f("ix_attachment_url"))
355
+ batch_op.drop_index(batch_op.f("ix_attachment_legacy_file_id"))
356
+
357
+ op.drop_table("attachment")
358
+ op.drop_table("user_account")
359
+ op.drop_table("bob")
360
+ op.drop_table("avatar")
361
+ # ### end Alembic commands ###