Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix mailings #23

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,10 @@ services:
POSTGRES_DB: pgdb
ports:
- 5432:5432
volumes:
- postgres_data:/var/lib/postgresql/data

redis:
image: redis
restart: unless-stopped
ports:
- 6379:6379

volumes:
postgres_data:
driver: local
4 changes: 3 additions & 1 deletion idb/bot/dialogs/admins/mailings/create/confirm.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,18 @@ async def on_click(
t = dialog_manager.dialog_data.get("time")
d = dialog_manager.dialog_data.get("date")
scheduled_at = parse_dt(t=t, d=d)
author_id: int = c.from_user.id
await save_mailing(
uow=uow,
bot=dialog_manager.middleware_data["bot"],
author_id=author_id,
title=dialog_manager.dialog_data["title"],
content=dialog_manager.dialog_data["content"],
scheduled_at=None if not scheduled_at else scheduled_at,
user_type_ids=dialog_manager.dialog_data["user_types"],
)
dialog_manager.show_mode = ShowMode.SEND
await c.bot.send_message(c.from_user.id, text="Рассылка создана") # type: ignore[union-attr]
await c.bot.send_message(author_id, text="Рассылка создана") # type: ignore[union-attr]
await dialog_manager.done()


Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
"""empty message

Revision ID: 41c796b69ba4
Revision ID: f0bb0f56f4aa
Revises:
Create Date: 2024-01-03 22:29:54.480730
Create Date: 2024-01-14 10:49:52.849965

"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "41c796b69ba4"
revision = "f0bb0f56f4aa"
down_revision = None
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"mailing",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("scheduled_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("status", sa.String(length=16), nullable=False),
sa.Column("sent_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("cancelled_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("title", sa.String(length=512), nullable=False),
sa.Column("content", sa.String(length=3072), nullable=False),
sa.Column(
"created_at",
sa.DateTime(timezone=True),
server_default=sa.text("TIMEZONE('utc', now())"),
nullable=False,
),
sa.Column(
"updated_at",
sa.DateTime(timezone=True),
server_default=sa.text("TIMEZONE('utc', now())"),
nullable=False,
),
sa.PrimaryKeyConstraint("id", name=op.f("pk__mailing")),
)
op.create_index(
op.f("ix__mailing__scheduled_at"), "mailing", ["scheduled_at"], unique=False
)
op.create_table(
"submenu",
sa.Column("id", sa.Integer(), nullable=False),
Expand Down Expand Up @@ -145,22 +119,37 @@ def upgrade() -> None:
op.f("ix__feedback__user_id"), "feedback", ["user_id"], unique=False
)
op.create_table(
"mailing_user_type",
sa.Column("mailing_id", sa.Integer(), nullable=False),
sa.Column("user_type_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["mailing_id"],
["mailing.id"],
name=op.f("fk__mailing_user_type__mailing_id__mailing"),
"mailing",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("author_id", sa.BigInteger(), nullable=False),
sa.Column("scheduled_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("status", sa.String(length=16), nullable=False),
sa.Column("sent_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("cancelled_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("title", sa.String(length=512), nullable=False),
sa.Column("content", sa.String(length=3072), nullable=False),
sa.Column(
"created_at",
sa.DateTime(timezone=True),
server_default=sa.text("TIMEZONE('utc', now())"),
nullable=False,
),
sa.ForeignKeyConstraint(
["user_type_id"],
["user_type.id"],
name=op.f("fk__mailing_user_type__user_type_id__user_type"),
sa.Column(
"updated_at",
sa.DateTime(timezone=True),
server_default=sa.text("TIMEZONE('utc', now())"),
nullable=False,
),
sa.PrimaryKeyConstraint(
"mailing_id", "user_type_id", name=op.f("pk__mailing_user_type")
sa.ForeignKeyConstraint(
["author_id"], ["users.id"], name=op.f("fk__mailing__author_id__users")
),
sa.PrimaryKeyConstraint("id", name=op.f("pk__mailing")),
)
op.create_index(
op.f("ix__mailing__author_id"), "mailing", ["author_id"], unique=False
)
op.create_index(
op.f("ix__mailing__scheduled_at"), "mailing", ["scheduled_at"], unique=False
)
op.create_table(
"user_type_user",
Expand Down Expand Up @@ -219,24 +208,43 @@ def upgrade() -> None:
op.create_index(
op.f("ix__answer__to_user_id"), "answer", ["to_user_id"], unique=False
)
op.create_table(
"mailing_user_type",
sa.Column("mailing_id", sa.Integer(), nullable=False),
sa.Column("user_type_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["mailing_id"],
["mailing.id"],
name=op.f("fk__mailing_user_type__mailing_id__mailing"),
),
sa.ForeignKeyConstraint(
["user_type_id"],
["user_type.id"],
name=op.f("fk__mailing_user_type__user_type_id__user_type"),
),
sa.PrimaryKeyConstraint(
"mailing_id", "user_type_id", name=op.f("pk__mailing_user_type")
),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("mailing_user_type")
op.drop_index(op.f("ix__answer__to_user_id"), table_name="answer")
op.drop_index(op.f("ix__answer__from_user_id"), table_name="answer")
op.drop_index(op.f("ix__answer__feedback_id"), table_name="answer")
op.drop_table("answer")
op.drop_table("user_type_user")
op.drop_table("mailing_user_type")
op.drop_index(op.f("ix__mailing__scheduled_at"), table_name="mailing")
op.drop_index(op.f("ix__mailing__author_id"), table_name="mailing")
op.drop_table("mailing")
op.drop_index(op.f("ix__feedback__user_id"), table_name="feedback")
op.drop_table("feedback")
op.drop_table("users")
op.drop_index(op.f("ix__user_type__name"), table_name="user_type")
op.drop_table("user_type")
op.drop_table("url")
op.drop_table("submenu")
op.drop_index(op.f("ix__mailing__scheduled_at"), table_name="mailing")
op.drop_table("mailing")
# ### end Alembic commands ###
3 changes: 3 additions & 0 deletions idb/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class Answer(TimestampMixin, Base):

class Mailing(TimestampMixin, Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
author_id: Mapped[int] = mapped_column(
BigInteger, ForeignKey("users.id"), nullable=False, index=True
)
scheduled_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True, index=True
)
Expand Down
5 changes: 3 additions & 2 deletions idb/db/repositories/mailing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from idb.db.models import MailingUserType as MailingUserTypeDb
from idb.db.repositories.base import Repository
from idb.exceptions import (
EntityNotFoundError,
InclusiveDanceError,
MailingNotFoundError,
)
Expand All @@ -34,6 +33,7 @@ async def get_by_id(self, mailing_id: int) -> Mailing:
async def create(
self,
*,
author_id: int,
title: str,
content: str,
scheduled_at: datetime | None,
Expand All @@ -43,6 +43,7 @@ async def create(
stmt = (
insert(MailingDb)
.values(
author_id=author_id,
title=title,
content=content,
scheduled_at=scheduled_at,
Expand Down Expand Up @@ -119,7 +120,7 @@ async def _update(self, *args: Any, **kwargs: Any) -> MailingDb:
obj = result.one()
await self._session.flush(obj)
except NoResultFound as e:
raise EntityNotFoundError from e
raise MailingNotFoundError from e
await self._session.refresh(obj)
return obj

Expand Down
8 changes: 7 additions & 1 deletion idb/logic/mailing.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,25 @@ async def process_new_mailing(uow: UnitOfWork, bot: Bot, mailing: Mailing) -> No
except Exception:
log.exception("Occured something")
now = datetime.now(tz=pytz.utc)
await uow.mailings.update_by_id(mailing_id=mailing.id, is_sent=True, sent_at=now)
await uow.mailings.update_by_id(
mailing_id=mailing.id,
status=MailingStatus.SENT,
sent_at=now,
)
await uow.commit()


async def save_mailing(
uow: UnitOfWork,
bot: Bot,
author_id: int,
title: str,
content: str,
scheduled_at: datetime | None,
user_type_ids: list[int],
) -> None:
mailing = await uow.mailings.create(
author_id=author_id,
title=title,
content=content,
scheduled_at=scheduled_at,
Expand Down
6 changes: 5 additions & 1 deletion tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
handle_constrained_string_or_bytes,
)

from idb.db.models import Feedback, Submenu, Url, User, UserType
from idb.db.models import Feedback, Mailing, Submenu, Url, User, UserType
from idb.generals.enums import SubmenuType


Expand Down Expand Up @@ -66,6 +66,10 @@ class FeedbackFactory(SQLAlchemyFactory[Feedback]):
__set_relationships__ = True


class MailingFeedback(SQLAlchemyFactory[Mailing]):
__model__ = Mailing


FACTORIES: tuple[SQLAlchemyFactory, ...] = (
UserFactory,
UserTypeFactory,
Expand Down
18 changes: 18 additions & 0 deletions tests/test_logic/test_mailing/test_update_mailing_by_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from datetime import datetime

import pytest

from idb.db.uow import UnitOfWork
from idb.exceptions.mailing import MailingNotFoundError
from idb.logic.mailing import update_mailing_by_id

DEFAULT_DT = datetime(year=2021, month=1, day=1)


async def test_mailing_not_found(uow: UnitOfWork) -> None:
with pytest.raises(MailingNotFoundError):
await update_mailing_by_id(
uow=uow,
mailing_id=-1,
sent_at=DEFAULT_DT,
)