slidge 0.1.3__py3-none-any.whl → 0.2.0a1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. slidge/__init__.py +3 -5
  2. slidge/__main__.py +2 -196
  3. slidge/__version__.py +5 -0
  4. slidge/command/adhoc.py +8 -1
  5. slidge/command/admin.py +6 -7
  6. slidge/command/base.py +1 -2
  7. slidge/command/register.py +32 -16
  8. slidge/command/user.py +85 -6
  9. slidge/contact/contact.py +165 -49
  10. slidge/contact/roster.py +122 -47
  11. slidge/core/config.py +14 -11
  12. slidge/core/gateway/base.py +148 -36
  13. slidge/core/gateway/caps.py +7 -5
  14. slidge/core/gateway/disco.py +2 -4
  15. slidge/core/gateway/mam.py +1 -4
  16. slidge/core/gateway/muc_admin.py +1 -1
  17. slidge/core/gateway/ping.py +2 -3
  18. slidge/core/gateway/presence.py +1 -1
  19. slidge/core/gateway/registration.py +32 -21
  20. slidge/core/gateway/search.py +3 -5
  21. slidge/core/gateway/session_dispatcher.py +120 -57
  22. slidge/core/gateway/vcard_temp.py +7 -5
  23. slidge/core/mixins/__init__.py +11 -1
  24. slidge/core/mixins/attachment.py +32 -14
  25. slidge/core/mixins/avatar.py +90 -25
  26. slidge/core/mixins/base.py +8 -2
  27. slidge/core/mixins/db.py +18 -0
  28. slidge/core/mixins/disco.py +0 -10
  29. slidge/core/mixins/message.py +18 -8
  30. slidge/core/mixins/message_maker.py +17 -9
  31. slidge/core/mixins/presence.py +17 -4
  32. slidge/core/pubsub.py +54 -220
  33. slidge/core/session.py +69 -34
  34. slidge/db/__init__.py +4 -0
  35. slidge/db/alembic/env.py +64 -0
  36. slidge/db/alembic/script.py.mako +26 -0
  37. slidge/db/alembic/versions/09f27f098baa_add_missing_attributes_in_room.py +36 -0
  38. slidge/db/alembic/versions/2461390c0af2_store_contacts_caps_verstring_in_db.py +36 -0
  39. slidge/db/alembic/versions/29f5280c61aa_store_subject_setter_in_room.py +37 -0
  40. slidge/db/alembic/versions/2b1f45ab7379_store_room_subject_setter_by_nickname.py +41 -0
  41. slidge/db/alembic/versions/82a4af84b679_add_muc_history_filled.py +48 -0
  42. slidge/db/alembic/versions/8d2ced764698_rely_on_db_to_store_contacts_rooms_and_.py +133 -0
  43. slidge/db/alembic/versions/aa9d82a7f6ef_db_creation.py +85 -0
  44. slidge/db/alembic/versions/b33993e87db3_move_everything_to_persistent_db.py +214 -0
  45. slidge/db/alembic/versions/b64b1a793483_add_source_and_legacy_id_for_archived_.py +48 -0
  46. slidge/db/alembic/versions/c4a8ec35a0e8_per_room_user_nick.py +34 -0
  47. slidge/db/alembic/versions/e91195719c2c_store_users_avatars_persistently.py +26 -0
  48. slidge/db/avatar.py +235 -0
  49. slidge/db/meta.py +65 -0
  50. slidge/db/models.py +375 -0
  51. slidge/db/store.py +1078 -0
  52. slidge/group/archive.py +58 -14
  53. slidge/group/bookmarks.py +72 -57
  54. slidge/group/participant.py +87 -28
  55. slidge/group/room.py +369 -211
  56. slidge/main.py +201 -0
  57. slidge/migration.py +30 -0
  58. slidge/slixfix/__init__.py +35 -2
  59. slidge/slixfix/roster.py +11 -4
  60. slidge/slixfix/xep_0292/vcard4.py +3 -0
  61. slidge/util/archive_msg.py +2 -1
  62. slidge/util/db.py +1 -47
  63. slidge/util/test.py +71 -4
  64. slidge/util/types.py +29 -4
  65. slidge/util/util.py +22 -0
  66. {slidge-0.1.3.dist-info → slidge-0.2.0a1.dist-info}/METADATA +4 -4
  67. slidge-0.2.0a1.dist-info/RECORD +114 -0
  68. slidge/core/cache.py +0 -183
  69. slidge/util/schema.sql +0 -126
  70. slidge/util/sql.py +0 -508
  71. slidge-0.1.3.dist-info/RECORD +0 -96
  72. {slidge-0.1.3.dist-info → slidge-0.2.0a1.dist-info}/LICENSE +0 -0
  73. {slidge-0.1.3.dist-info → slidge-0.2.0a1.dist-info}/WHEEL +0 -0
  74. {slidge-0.1.3.dist-info → slidge-0.2.0a1.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,64 @@
1
+ from alembic import context
2
+
3
+ from slidge import global_config
4
+ from slidge.db.meta import Base, get_engine
5
+
6
+ config = context.config
7
+
8
+ target_metadata = Base.metadata
9
+
10
+
11
+ def run_migrations_offline() -> None:
12
+ """Run migrations in 'offline' mode.
13
+
14
+ This configures the context with just a URL
15
+ and not an Engine, though an Engine is acceptable
16
+ here as well. By skipping the Engine creation
17
+ we don't even need a DBAPI to be available.
18
+
19
+ Calls to context.execute() here emit the given string to the
20
+ script output.
21
+
22
+ """
23
+ url = config.get_main_option("sqlalchemy.url")
24
+ context.configure(
25
+ url=url,
26
+ target_metadata=target_metadata,
27
+ literal_binds=True,
28
+ dialect_opts={"paramstyle": "named"},
29
+ render_as_batch=True,
30
+ )
31
+
32
+ with context.begin_transaction():
33
+ context.run_migrations()
34
+
35
+
36
+ def run_migrations_online() -> None:
37
+ """Run migrations in 'online' mode.
38
+
39
+ In this scenario we need to create an Engine
40
+ and associate a connection with the context.
41
+
42
+ """
43
+ try:
44
+ # in prod
45
+ connectable = get_engine(global_config.DB_URL)
46
+ except AttributeError:
47
+ # during dev, to generate migrations
48
+ connectable = get_engine("sqlite+pysqlite:///dev/slidge.sqlite")
49
+
50
+ with connectable.connect() as connection:
51
+ context.configure(
52
+ connection=connection,
53
+ target_metadata=target_metadata,
54
+ render_as_batch=True,
55
+ )
56
+
57
+ with context.begin_transaction():
58
+ context.run_migrations()
59
+
60
+
61
+ if context.is_offline_mode():
62
+ run_migrations_offline()
63
+ else:
64
+ run_migrations_online()
@@ -0,0 +1,26 @@
1
+ """${message}
2
+
3
+ Revision ID: ${up_revision}
4
+ Revises: ${down_revision | comma,n}
5
+ Create Date: ${create_date}
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ ${imports if imports else ""}
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
19
+
20
+
21
+ def upgrade() -> None:
22
+ ${upgrades if upgrades else "pass"}
23
+
24
+
25
+ def downgrade() -> None:
26
+ ${downgrades if downgrades else "pass"}
@@ -0,0 +1,36 @@
1
+ """Add n_participants attributes to Room
2
+
3
+ Should have been part of another commit, but I messed up some rebase
4
+
5
+ Revision ID: 09f27f098baa
6
+ Revises: 29f5280c61aa
7
+ Create Date: 2024-07-11 10:54:21.155871
8
+
9
+ """
10
+
11
+ from typing import Sequence, Union
12
+
13
+ import sqlalchemy as sa
14
+ from alembic import op
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "09f27f098baa"
18
+ down_revision: Union[str, None] = "29f5280c61aa"
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
+ with op.batch_alter_table("room", schema=None) as batch_op:
26
+ batch_op.add_column(sa.Column("n_participants", sa.Integer(), nullable=True))
27
+
28
+ # ### end Alembic commands ###
29
+
30
+
31
+ def downgrade() -> None:
32
+ # ### commands auto generated by Alembic - please adjust! ###
33
+ with op.batch_alter_table("room", schema=None) as batch_op:
34
+ batch_op.drop_column("n_participants")
35
+
36
+ # ### end Alembic commands ###
@@ -0,0 +1,36 @@
1
+ """Store contacts caps verstring in DB
2
+
3
+ Revision ID: 2461390c0af2
4
+ Revises: 2b1f45ab7379
5
+ Create Date: 2024-07-20 08:00:11.675735
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = "2461390c0af2"
16
+ down_revision: Union[str, None] = "2b1f45ab7379"
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ # ### commands auto generated by Alembic - please adjust! ###
23
+ with op.batch_alter_table("contact", schema=None) as batch_op:
24
+ batch_op.add_column(sa.Column("caps_ver_bare", sa.String(), nullable=True))
25
+ batch_op.add_column(sa.Column("caps_ver", sa.String(), nullable=True))
26
+
27
+ # ### end Alembic commands ###
28
+
29
+
30
+ def downgrade() -> None:
31
+ # ### commands auto generated by Alembic - please adjust! ###
32
+ with op.batch_alter_table("contact", schema=None) as batch_op:
33
+ batch_op.drop_column("caps_ver")
34
+ batch_op.drop_column("caps_ver_bare")
35
+
36
+ # ### end Alembic commands ###
@@ -0,0 +1,37 @@
1
+ """Store subject setter in Room
2
+
3
+ Revision ID: 29f5280c61aa
4
+ Revises: 8d2ced764698
5
+ Create Date: 2024-07-10 13:09:25.181594
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = "29f5280c61aa"
16
+ down_revision: Union[str, None] = "8d2ced764698"
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ with op.batch_alter_table("room", schema=None) as batch_op:
23
+ batch_op.add_column(sa.Column("subject_setter_id", sa.Integer(), nullable=True))
24
+ # we give this constraint a name a workaround for
25
+ # https://github.com/sqlalchemy/alembic/issues/1195
26
+ batch_op.create_foreign_key(
27
+ "subject_setter_id_foreign_key",
28
+ "participant",
29
+ ["subject_setter_id"],
30
+ ["id"],
31
+ )
32
+
33
+
34
+ def downgrade() -> None:
35
+ with op.batch_alter_table("room", schema=None) as batch_op:
36
+ batch_op.drop_constraint("subject_setter_id_foreign_key", type_="foreignkey")
37
+ batch_op.drop_column("subject_setter_id")
@@ -0,0 +1,41 @@
1
+ """Store room subject setter by nickname
2
+
3
+ Revision ID: 2b1f45ab7379
4
+ Revises: c4a8ec35a0e8
5
+ Create Date: 2024-07-20 00:14:36.882689
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision: str = "2b1f45ab7379"
16
+ down_revision: Union[str, None] = "c4a8ec35a0e8"
17
+ branch_labels: Union[str, Sequence[str], None] = None
18
+ depends_on: Union[str, Sequence[str], None] = None
19
+
20
+
21
+ def upgrade() -> None:
22
+ # ### commands auto generated by Alembic - please adjust! ###
23
+ with op.batch_alter_table("room", schema=None) as batch_op:
24
+ batch_op.add_column(sa.Column("subject_setter", sa.String(), nullable=True))
25
+ batch_op.drop_constraint("subject_setter_id_foreign_key", type_="foreignkey")
26
+ batch_op.drop_column("subject_setter_id")
27
+ # ### end Alembic commands ###
28
+
29
+
30
+ def downgrade() -> None:
31
+ # ### commands auto generated by Alembic - please adjust! ###
32
+ with op.batch_alter_table("room", schema=None) as batch_op:
33
+ batch_op.add_column(sa.Column("subject_setter_id", sa.INTEGER(), nullable=True))
34
+ batch_op.create_foreign_key(
35
+ "subject_setter_id_foreign_key",
36
+ "participant",
37
+ ["subject_setter_id"],
38
+ ["id"],
39
+ )
40
+ batch_op.drop_column("subject_setter")
41
+ # ### end Alembic commands ###
@@ -0,0 +1,48 @@
1
+ """Add MUC.history_filled
2
+
3
+ Also drop caps_ver_bare column that should never have been added.
4
+
5
+ Revision ID: 82a4af84b679
6
+ Revises: 2461390c0af2
7
+ Create Date: 2024-07-22 07:01:05.352737
8
+
9
+ """
10
+
11
+ from typing import Sequence, Union
12
+
13
+ import sqlalchemy as sa
14
+ from alembic import op
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "82a4af84b679"
18
+ down_revision: Union[str, None] = "2461390c0af2"
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
+ with op.batch_alter_table("contact", schema=None) as batch_op:
26
+ batch_op.drop_column("caps_ver_bare")
27
+
28
+ with op.batch_alter_table("room", schema=None) as batch_op:
29
+ batch_op.add_column(
30
+ sa.Column(
31
+ "history_filled",
32
+ sa.Boolean(),
33
+ nullable=False,
34
+ server_default=sa.False_(), # manually added
35
+ )
36
+ )
37
+ # ### end Alembic commands ###
38
+
39
+
40
+ def downgrade() -> None:
41
+ # ### commands auto generated by Alembic - please adjust! ###
42
+ with op.batch_alter_table("room", schema=None) as batch_op:
43
+ batch_op.drop_column("history_filled")
44
+
45
+ with op.batch_alter_table("contact", schema=None) as batch_op:
46
+ batch_op.add_column(sa.Column("caps_ver_bare", sa.VARCHAR(), nullable=True))
47
+
48
+ # ### end Alembic commands ###
@@ -0,0 +1,133 @@
1
+ """Rely on DB to store contacts, rooms and participants
2
+
3
+ Revision ID: 8d2ced764698
4
+ Revises: b33993e87db3
5
+ Create Date: 2024-07-08 14:39:47.022088
6
+
7
+ """
8
+
9
+ from typing import Sequence, Union
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ import slidge.db.meta
15
+
16
+ # revision identifiers, used by Alembic.
17
+ revision: str = "8d2ced764698"
18
+ down_revision: Union[str, None] = "b33993e87db3"
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
+ op.create_table(
25
+ "hat",
26
+ sa.Column("id", sa.Integer(), nullable=False),
27
+ sa.Column("title", sa.String(), nullable=False),
28
+ sa.Column("uri", sa.String(), nullable=False),
29
+ sa.PrimaryKeyConstraint("id"),
30
+ sa.UniqueConstraint("title", "uri"),
31
+ )
32
+ op.create_table(
33
+ "contact_sent",
34
+ sa.Column("id", sa.Integer(), nullable=False),
35
+ sa.Column("contact_id", sa.Integer(), nullable=False),
36
+ sa.Column("msg_id", sa.String(), nullable=False),
37
+ sa.ForeignKeyConstraint(
38
+ ["contact_id"],
39
+ ["contact.id"],
40
+ ),
41
+ sa.PrimaryKeyConstraint("id"),
42
+ sa.UniqueConstraint("contact_id", "msg_id"),
43
+ )
44
+ op.create_table(
45
+ "participant",
46
+ sa.Column("id", sa.Integer(), nullable=False),
47
+ sa.Column("room_id", sa.Integer(), nullable=False),
48
+ sa.Column("contact_id", sa.Integer(), nullable=True),
49
+ sa.Column("is_user", sa.Boolean(), nullable=False),
50
+ sa.Column(
51
+ "affiliation",
52
+ sa.Enum("outcast", "member", "admin", "owner", "none", native_enum=False),
53
+ nullable=False,
54
+ ),
55
+ sa.Column(
56
+ "role",
57
+ sa.Enum("moderator", "participant", "visitor", "none", native_enum=False),
58
+ nullable=False,
59
+ ),
60
+ sa.Column("presence_sent", sa.Boolean(), nullable=False),
61
+ sa.Column("resource", sa.String(), nullable=True),
62
+ sa.Column("nickname", sa.String(), nullable=True),
63
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
64
+ sa.ForeignKeyConstraint(
65
+ ["contact_id"],
66
+ ["contact.id"],
67
+ ),
68
+ sa.ForeignKeyConstraint(
69
+ ["room_id"],
70
+ ["room.id"],
71
+ ),
72
+ sa.PrimaryKeyConstraint("id"),
73
+ )
74
+ op.create_table(
75
+ "participant_hats",
76
+ sa.Column("participant_id", sa.Integer(), nullable=False),
77
+ sa.Column("hat_id", sa.Integer(), nullable=False),
78
+ sa.ForeignKeyConstraint(
79
+ ["hat_id"],
80
+ ["hat.id"],
81
+ ),
82
+ sa.ForeignKeyConstraint(
83
+ ["participant_id"],
84
+ ["participant.id"],
85
+ ),
86
+ sa.PrimaryKeyConstraint("participant_id", "hat_id"),
87
+ )
88
+ op.add_column("contact", sa.Column("is_friend", sa.Boolean(), nullable=False))
89
+ op.add_column("contact", sa.Column("added_to_roster", sa.Boolean(), nullable=False))
90
+ op.add_column(
91
+ "contact",
92
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
93
+ )
94
+ op.add_column("contact", sa.Column("updated", sa.Boolean(), nullable=False))
95
+ op.add_column("room", sa.Column("description", sa.String(), nullable=True))
96
+ op.add_column("room", sa.Column("subject", sa.String(), nullable=True))
97
+ op.add_column("room", sa.Column("subject_date", sa.DateTime(), nullable=True))
98
+ op.add_column(
99
+ "room",
100
+ sa.Column(
101
+ "muc_type",
102
+ sa.Enum("GROUP", "CHANNEL", "CHANNEL_NON_ANONYMOUS", name="muctype"),
103
+ nullable=True,
104
+ ),
105
+ )
106
+ op.add_column("room", sa.Column("user_resources", sa.String(), nullable=True))
107
+ op.add_column(
108
+ "room", sa.Column("participants_filled", sa.Boolean(), nullable=False)
109
+ )
110
+ op.add_column(
111
+ "room",
112
+ sa.Column("extra_attributes", slidge.db.meta.JSONEncodedDict(), nullable=True),
113
+ )
114
+ op.add_column("room", sa.Column("updated", sa.Boolean(), nullable=False))
115
+
116
+
117
+ def downgrade() -> None:
118
+ op.drop_column("room", "updated")
119
+ op.drop_column("room", "extra_attributes")
120
+ op.drop_column("room", "participants_filled")
121
+ op.drop_column("room", "user_resources")
122
+ op.drop_column("room", "muc_type")
123
+ op.drop_column("room", "subject_date")
124
+ op.drop_column("room", "subject")
125
+ op.drop_column("room", "description")
126
+ op.drop_column("contact", "updated")
127
+ op.drop_column("contact", "extra_attributes")
128
+ op.drop_column("contact", "added_to_roster")
129
+ op.drop_column("contact", "is_friend")
130
+ op.drop_table("participant_hats")
131
+ op.drop_table("participant")
132
+ op.drop_table("contact_sent")
133
+ op.drop_table("hat")
@@ -0,0 +1,85 @@
1
+ """DB Creation
2
+
3
+ Including a migration from the user_store shelf
4
+
5
+ Revision ID: aa9d82a7f6ef
6
+ Revises:
7
+ Create Date: 2024-04-17 20:57:01.357041
8
+
9
+ """
10
+
11
+ import logging
12
+ from datetime import datetime
13
+ from typing import Sequence, Union
14
+
15
+ import sqlalchemy as sa
16
+ from alembic import op
17
+
18
+ import slidge.db.meta
19
+
20
+ # revision identifiers, used by Alembic.
21
+ revision: str = "aa9d82a7f6ef"
22
+ down_revision: Union[str, None] = None
23
+ branch_labels: Union[str, Sequence[str], None] = None
24
+ depends_on: Union[str, Sequence[str], None] = None
25
+
26
+
27
+ def upgrade() -> None:
28
+ # ### commands auto generated by Alembic - please adjust! ###
29
+ accounts = op.create_table(
30
+ "user_account",
31
+ sa.Column("id", sa.Integer(), nullable=False),
32
+ sa.Column("jid", slidge.db.meta.JIDType(), nullable=False),
33
+ sa.Column(
34
+ "registration_date",
35
+ sa.DateTime(),
36
+ server_default=sa.text("(CURRENT_TIMESTAMP)"),
37
+ nullable=False,
38
+ ),
39
+ sa.Column(
40
+ "legacy_module_data", slidge.db.meta.JSONEncodedDict(), nullable=False
41
+ ),
42
+ sa.Column("preferences", slidge.db.meta.JSONEncodedDict(), nullable=False),
43
+ sa.PrimaryKeyConstraint("id"),
44
+ sa.UniqueConstraint("jid"),
45
+ )
46
+ # ### end Alembic commands ###
47
+ try:
48
+ migrate_from_shelf(accounts)
49
+ except Exception:
50
+ downgrade()
51
+ raise
52
+
53
+
54
+ def downgrade() -> None:
55
+ # ### commands auto generated by Alembic - please adjust! ###
56
+ op.drop_table("user_account")
57
+ # ### end Alembic commands ###
58
+
59
+
60
+ def migrate_from_shelf(accounts: sa.Table) -> None:
61
+ try:
62
+ from slidge.util.db import user_store
63
+ except ImportError:
64
+ return
65
+ try:
66
+ users = list(user_store.get_all())
67
+ except AttributeError:
68
+ return
69
+ logging.info("Migrating %s users from the deprecated user_store shelf", len(users))
70
+ op.bulk_insert(
71
+ accounts,
72
+ [
73
+ {
74
+ "jid": user.jid,
75
+ "registration_date": (
76
+ user.registration_date
77
+ if user.registration_date is not None
78
+ else datetime.now()
79
+ ),
80
+ "legacy_module_data": user.registration_form,
81
+ "preferences": {},
82
+ }
83
+ for user in users
84
+ ],
85
+ )