Skip to content

Commit 3359b85

Browse files
authored
Группы как сущность (#30)
## Изменения - Группы выделены в отдельную сущность и созданы подтипы для групп тг/вк - Добавлен create_ts для вебхук стоража - Группы тг теперь создаются автоматически
1 parent d5e4f84 commit 3359b85

21 files changed

Lines changed: 377 additions & 73 deletions

.github/workflows/checks.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Python tests
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
test:
8+
name: Unit tests
9+
runs-on: ubuntu-latest
10+
services:
11+
postgres:
12+
image: postgres:15
13+
env:
14+
POSTGRES_HOST_AUTH_METHOD: trust
15+
options: >-
16+
--health-cmd pg_isready
17+
--health-interval 10s
18+
--health-timeout 5s
19+
--health-retries 5
20+
-p 5432:5432
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
- uses: actions/setup-python@v4
25+
with:
26+
python-version: "3.11"
27+
- name: Install dependencies
28+
run: |
29+
python -m ensurepip
30+
python -m pip install --upgrade pip
31+
pip install --upgrade -r requirements.txt -r requirements.dev.txt
32+
- name: Migrate DB
33+
run: |
34+
DB_DSN=postgresql://postgres@localhost:5432/postgres alembic upgrade head
35+
- name: Build coverage file
36+
id: pytest
37+
run: |
38+
DB_DSN=postgresql://postgres@localhost:5432/postgres pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=services_backend tests/ | tee pytest-coverage.txt
39+
exit ${PIPESTATUS[0]}
40+
- name: Print report
41+
if: always()
42+
run: |
43+
cat pytest-coverage.txt
44+
- name: Pytest coverage comment
45+
uses: MishaKav/pytest-coverage-comment@main
46+
with:
47+
pytest-coverage-path: ./pytest-coverage.txt
48+
title: Coverage Report
49+
badge-title: Code Coverage
50+
hide-badge: false
51+
hide-report: false
52+
create-new-comment: false
53+
hide-comment: false
54+
report-only-changed-files: false
55+
remove-link-from-badge: false
56+
junitxml-path: ./pytest.xml
57+
junitxml-title: Summary
58+
- name: Fail on pytest errors
59+
if: steps.pytest.outcome == 'failure'
60+
run: exit 1
61+
62+
linting:
63+
runs-on: ubuntu-latest
64+
steps:
65+
- uses: actions/checkout@v4
66+
- uses: actions/setup-python@v2
67+
with:
68+
python-version: 3.11
69+
- uses: isort/isort-action@master
70+
with:
71+
requirementsFiles: "requirements.txt requirements.dev.txt"
72+
- uses: psf/black@stable
73+
- name: Comment if linting failed
74+
if: failure()
75+
uses: thollander/actions-comment-pull-request@v2
76+
with:
77+
message: |
78+
:poop: Code linting failed, use `black` and `isort` to fix it.

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ format: configure
55
source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./social
66
source ./venv/bin/activate && isort ./social
77
source ./venv/bin/activate && black ./social
8+
source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./tests
9+
source ./venv/bin/activate && isort ./tests
10+
source ./venv/bin/activate && black ./tests
11+
source ./venv/bin/activate && autoflake -r --in-place --remove-all-unused-imports ./migrations
12+
source ./venv/bin/activate && isort ./migrations
13+
source ./venv/bin/activate && black ./migrations
814

915
configure: venv
1016
source ./venv/bin/activate && pip install -r requirements.dev.txt -r requirements.txt
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"""User defined groups
2+
3+
Revision ID: 1cacaf803a1d
4+
Revises: 9d98c1e9c864
5+
Create Date: 2024-04-14 23:38:18.956845
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
from sqlalchemy.schema import CreateSequence, Sequence
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision = '1cacaf803a1d'
16+
down_revision = '9d98c1e9c864'
17+
branch_labels = None
18+
depends_on = None
19+
20+
21+
def upgrade():
22+
op.create_table(
23+
'group',
24+
sa.Column('id', sa.Integer(), nullable=False),
25+
sa.Column('type', sa.String(), nullable=False),
26+
sa.Column('owner_id', sa.Integer(), nullable=True),
27+
sa.Column('is_deleted', sa.Boolean(), nullable=False),
28+
sa.Column('last_active_ts', sa.DateTime(), nullable=False),
29+
sa.Column('create_ts', sa.DateTime(), nullable=False),
30+
sa.Column('update_ts', sa.DateTime(), nullable=False),
31+
)
32+
op.execute(
33+
'''
34+
INSERT INTO "group"
35+
(id, type, is_deleted, last_active_ts, create_ts, update_ts)
36+
SELECT id, 'vk_group', False, now(), create_ts, update_ts
37+
FROM vk_groups;
38+
'''
39+
)
40+
41+
max_id = op.get_bind().execute(sa.text('SELECT MAX(id) FROM "group";')).scalar() or 0
42+
op.create_primary_key('group_pk', 'group', ['id'])
43+
op.execute(CreateSequence(Sequence('group_id_seq', max_id + 1)))
44+
op.alter_column('group', 'id', server_default=sa.text('nextval(\'group_id_seq\')'))
45+
46+
op.create_table(
47+
'telegram_channel',
48+
sa.Column('id', sa.Integer(), nullable=False),
49+
sa.Column('channel_id', sa.BigInteger(), nullable=False),
50+
sa.ForeignKeyConstraint(
51+
['id'],
52+
['group.id'],
53+
),
54+
sa.PrimaryKeyConstraint('id'),
55+
)
56+
op.create_table(
57+
'telegram_chat',
58+
sa.Column('id', sa.Integer(), nullable=False),
59+
sa.Column('chat_id', sa.BigInteger(), nullable=False),
60+
sa.ForeignKeyConstraint(
61+
['id'],
62+
['group.id'],
63+
),
64+
sa.PrimaryKeyConstraint('id'),
65+
)
66+
op.create_table(
67+
'vk_chat',
68+
sa.Column('id', sa.Integer(), nullable=False),
69+
sa.Column('peer_id', sa.Integer(), nullable=False),
70+
sa.ForeignKeyConstraint(
71+
['id'],
72+
['group.id'],
73+
),
74+
sa.PrimaryKeyConstraint('id'),
75+
)
76+
op.create_foreign_key('group_vkgroup_fk', 'vk_groups', 'group', ['id'], ['id'])
77+
op.drop_column('vk_groups', 'update_ts')
78+
op.drop_column('vk_groups', 'create_ts')
79+
op.execute('DROP SEQUENCE IF EXISTS vk_groups_id_seq CASCADE;')
80+
op.rename_table('vk_groups', 'vk_group')
81+
82+
83+
def downgrade():
84+
op.rename_table('vk_group', 'vk_groups')
85+
86+
max_id = op.get_bind().execute(sa.text('SELECT MAX(id) FROM "vk_groups";')).scalar() or 0
87+
op.execute(CreateSequence(Sequence('vk_groups_id_seq', max_id + 1)))
88+
op.alter_column('vk_groups', 'id', server_default=sa.text('nextval(\'vk_groups_id_seq\')'))
89+
90+
op.add_column('vk_groups', sa.Column('create_ts', sa.DateTime()))
91+
op.add_column('vk_groups', sa.Column('update_ts', sa.DateTime()))
92+
op.execute('UPDATE vk_groups SET create_ts = (SELECT create_ts FROM "group" WHERE "group".id = vk_groups.id);')
93+
op.execute('UPDATE vk_groups SET update_ts = (SELECT update_ts FROM "group" WHERE "group".id = vk_groups.id);')
94+
op.alter_column('vk_groups', 'create_ts', nullable=False)
95+
op.alter_column('vk_groups', 'update_ts', nullable=False)
96+
op.drop_constraint('group_vkgroup_fk', 'vk_groups', type_='foreignkey')
97+
op.drop_table('vk_chat')
98+
op.drop_table('telegram_chat')
99+
op.drop_table('telegram_channel')
100+
op.drop_table('group')
101+
op.execute('DROP SEQUENCE IF EXISTS group_id_seq CASCADE;')

migrations/versions/57c72962d2b4_webhook_storage.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Create Date: 2023-03-12 14:22:34.958257
66
77
"""
8+
89
import sqlalchemy as sa
910
from alembic import op
1011

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""WebhookStorage event_ts
2+
3+
Revision ID: 62addefd9655
4+
Revises: 1cacaf803a1d
5+
Create Date: 2024-04-15 00:21:54.075449
6+
7+
"""
8+
9+
import sqlalchemy as sa
10+
from alembic import op
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = '62addefd9655'
15+
down_revision = '1cacaf803a1d'
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
op.add_column('webhook_storage', sa.Column('event_ts', sa.DateTime(), nullable=True))
22+
23+
24+
def downgrade():
25+
op.drop_column('webhook_storage', 'event_ts')

migrations/versions/9d98c1e9c864_vk.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
Create Date: 2023-08-19 15:53:19.787309
66
77
"""
8-
from alembic import op
8+
99
import sqlalchemy as sa
10+
from alembic import op
1011

1112

1213
# revision identifiers, used by Alembic.
@@ -17,14 +18,15 @@
1718

1819

1920
def upgrade():
20-
op.create_table('vk_groups',
21+
op.create_table(
22+
'vk_groups',
2123
sa.Column('id', sa.Integer(), nullable=False),
2224
sa.Column('group_id', sa.Integer(), nullable=False),
2325
sa.Column('confirmation_token', sa.String(), nullable=False),
2426
sa.Column('secret_key', sa.String(), nullable=False),
2527
sa.Column('create_ts', sa.DateTime(), nullable=False),
2628
sa.Column('update_ts', sa.DateTime(), nullable=False),
27-
sa.PrimaryKeyConstraint('id')
29+
sa.PrimaryKeyConstraint('id'),
2830
)
2931

3032

social/handlers_discord/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from collections.abc import Callable
3+
34
from social.utils.events import EventProcessor
45

56

social/handlers_github/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
from collections.abc import Callable
3+
34
from social.utils.events import EventProcessor
45

56

social/handlers_telegram/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
@lru_cache()
1919
def get_application():
20+
if not settings.TELEGRAM_BOT_TOKEN:
21+
return None
2022
context_types = ContextTypes(context=CustomContext)
2123
app = Application.builder().token(settings.TELEGRAM_BOT_TOKEN).updater(None).context_types(context_types).build()
2224
logger.info("Telegram API initialized successfully")

social/handlers_telegram/handlers_viribus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Для создания нового обработчика создай асинхронную функцию в конце файла с параметрами
44
Update и Context, а потом зарегистрируй ее внутри функции `register_handlers`.
55
"""
6+
67
import logging
78
from random import choice
89
from string import ascii_letters, digits, punctuation

0 commit comments

Comments
 (0)