Skip to content

Commit

Permalink
Let's solve problems as they arise© (undo some DB optimizations until…
Browse files Browse the repository at this point in the history
… we really need it + move global settings back to DB)
  • Loading branch information
Arutemu64 committed Sep 6, 2023
1 parent 47e1947 commit 46579c2
Show file tree
Hide file tree
Showing 22 changed files with 215 additions and 160 deletions.
34 changes: 34 additions & 0 deletions alembic/versions/006_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""settings
Revision ID: 006
Revises: 005
Create Date: 2023-09-04 21:21:07.347317
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '006'
down_revision = '005'
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('settings',
sa.Column('id', sa.Integer(), server_default='1', nullable=False),
sa.Column('voting_enabled', sa.Boolean(), server_default='False', nullable=False),
sa.Column('announcement_timestamp', sa.Float(), server_default='0', nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_settings')),
sa.UniqueConstraint('id', name=op.f('uq_settings_id'))
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('settings')
# ### end Alembic commands ###
23 changes: 15 additions & 8 deletions src/bot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
from aiogram.fsm.storage.memory import SimpleEventIsolation
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
from aiohttp import web
from redis.asyncio.client import Redis
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.redis import RedisIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

from src.bot.dispatcher import get_dispatcher
from src.config import conf
from src.db.database import Database, create_session_maker
from src.redis import build_redis_client, get_redis_storage
from src.redis.global_settings import GlobalSettings

BOT_TOKEN = conf.bot.token

Expand All @@ -26,10 +26,12 @@ async def on_startup(bot: Bot) -> None:
)


async def setup_default_settings(redis: Redis) -> None:
settings = GlobalSettings(redis)
await settings.voting_enabled.create(False)
await settings.announcement_timestamp.create(0)
async def setup_default_settings(session_pool) -> None:
async with session_pool() as session:
db = Database(session)
if not await db.settings.exists():
await db.settings.create(voting_enabled=False, announcement_timestamp=0)
await db.session.commit()


async def main() -> None:
Expand All @@ -42,18 +44,23 @@ async def main() -> None:
AsyncioIntegration(),
AioHttpIntegration(),
SqlalchemyIntegration(),
RedisIntegration(),
],
)

bot = Bot(token=BOT_TOKEN, parse_mode=ParseMode.HTML)

redis = build_redis_client()
asyncio.create_task(redis.ping())
await setup_default_settings(redis)
storage = get_redis_storage(redis=redis)

session_pool = create_session_maker()
await setup_default_settings(session_pool)

dp = get_dispatcher(
storage=storage, event_isolation=SimpleEventIsolation(), redis=redis
storage=storage,
event_isolation=SimpleEventIsolation(),
session_pool=session_pool,
)

await bot.delete_webhook(drop_pending_updates=True)
Expand Down
7 changes: 0 additions & 7 deletions src/bot/dialogs/main/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Any

from aiogram.fsm.context import FSMContext
from aiogram_dialog import Dialog, DialogManager, LaunchMode, StartMode

from src.bot.dialogs import states
Expand All @@ -13,19 +12,13 @@

async def on_start_main(start_data: Any, manager: DialogManager):
db: Database = manager.middleware_data["db"]
state: FSMContext = manager.middleware_data["state"]

# Проверка регистрации
user = await db.user.get(manager.event.from_user.id)
if user:
if user.username != manager.event.from_user.username:
user.username = manager.event.from_user.username
await db.session.commit()
await state.update_data(
user_role=user.role,
items_per_page=user.items_per_page,
receive_all_announcements=user.receive_all_announcements,
)
else:
await manager.event.answer(strings.common.welcome)
await manager.start(states.REGISTRATION.MAIN, mode=StartMode.RESET_STACK)
Expand Down
17 changes: 7 additions & 10 deletions src/bot/dialogs/main/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,22 @@
from src.bot.structures import UserRole
from src.bot.ui import images, strings
from src.db import Database
from src.redis.global_settings import GlobalSettings


async def main_menu_getter(
dialog_manager: DialogManager, settings: GlobalSettings, db: Database, **kwargs
):
user_data = await dialog_manager.middleware_data["state"].get_data()
dialog_manager.dialog_data["voting_enabled"] = await settings.voting_enabled.get()
async def main_menu_getter(dialog_manager: DialogManager, db: Database, **kwargs):
user_role = await db.user.get_role(dialog_manager.event.from_user.id)
return {
"name": dialog_manager.event.from_user.first_name,
"is_helper": user_data["user_role"] in [UserRole.HELPER, UserRole.ORG],
"is_org": user_data["user_role"] == UserRole.ORG,
"is_helper": user_role in [UserRole.HELPER, UserRole.ORG],
"is_org": user_role == UserRole.ORG,
"random_quote": random.choice(strings.quotes),
"voting_enabled": dialog_manager.dialog_data["voting_enabled"],
"voting_enabled": await db.settings.get_voting_enabled(),
}


async def open_voting(callback: CallbackQuery, button: Button, manager: DialogManager):
if manager.dialog_data.get("voting_enabled"):
db: Database = manager.middleware_data["db"]
if await db.settings.get_voting_enabled():
await manager.start(state=states.VOTING.NOMINATIONS)
else:
await callback.answer(strings.errors.voting_disabled, show_alert=True)
Expand Down
9 changes: 4 additions & 5 deletions src/bot/dialogs/org/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from src.bot.ui import strings
from src.db import Database
from src.db.models import Event, Nomination, User
from src.redis.global_settings import GlobalSettings

# fmt: off
StatsTemplate = Jinja( # noqa
Expand All @@ -27,8 +26,8 @@
# fmt: on


async def org_menu_getter(db: Database, settings: GlobalSettings, **kwargs):
voting_enabled = await settings.voting_enabled.get()
async def org_menu_getter(db: Database, **kwargs):
voting_enabled = await db.settings.get_voting_enabled()
return {
"voting_enabled": voting_enabled,
"bot_info": (
Expand Down Expand Up @@ -91,8 +90,8 @@ async def org_menu_getter(db: Database, settings: GlobalSettings, **kwargs):
async def switch_voting(
callback: CallbackQuery, button: Button, manager: DialogManager
):
settings: GlobalSettings = manager.middleware_data["settings"]
await settings.voting_enabled.set(not await settings.voting_enabled.get())
db: Database = manager.middleware_data["db"]
await db.settings.toggle_voting()


org_menu = Window(
Expand Down
7 changes: 5 additions & 2 deletions src/bot/dialogs/schedule/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@

async def on_start_schedule(start_data: dict, manager: DialogManager):
db: Database = manager.middleware_data["db"]
user_data = await manager.middleware_data["state"].get_data()
user = await db.user.get(manager.event.from_user.id)

manager.dialog_data["role"] = user.role
manager.dialog_data["events_per_page"] = user.items_per_page

current_event = await db.event.get_current()
await set_schedule_page(manager, current_event)

schedule_loader = ScheduleLoader(
db=db,
events_per_page=user_data["items_per_page"],
events_per_page=manager.dialog_data["events_per_page"],
)
manager.dialog_data["pages"] = await schedule_loader.get_pages_count()

Expand Down
16 changes: 7 additions & 9 deletions src/bot/dialogs/schedule/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@


async def schedule_getter(dialog_manager: DialogManager, db: Database, **kwargs):
user_data = await dialog_manager.middleware_data["state"].get_data()
schedule_loader = ScheduleLoader(
db=db,
events_per_page=user_data["items_per_page"],
events_per_page=dialog_manager.dialog_data["events_per_page"],
search_query=dialog_manager.dialog_data.get("search_query"),
)
pages = dialog_manager.dialog_data["pages"]
Expand All @@ -88,18 +87,19 @@ async def schedule_getter(dialog_manager: DialogManager, db: Database, **kwargs)
"events": events,
"subscription_ids": subscription_ids,
"is_helper": True
if user_data["user_role"] in [UserRole.HELPER, UserRole.ORG]
if dialog_manager.dialog_data["role"] in [UserRole.HELPER, UserRole.ORG]
else False,
}


async def set_schedule_page(manager: DialogManager, event: Event):
db: Database = manager.middleware_data["db"]
user_data = await manager.middleware_data["state"].get_data()

if event:
search_query = manager.dialog_data.get("search_query")
events_loader = ScheduleLoader(db, user_data["items_per_page"], search_query)
events_loader = ScheduleLoader(
db, manager.dialog_data["events_per_page"], search_query
)
page = await events_loader.get_page_number(event)
await manager.find(ID_SCHEDULE_SCROLL).set_page(page)
else:
Expand Down Expand Up @@ -131,12 +131,11 @@ async def set_search_query(
data: str,
):
db: Database = dialog_manager.middleware_data["db"]
user_data = await dialog_manager.middleware_data["state"].get_data()
dialog_manager.dialog_data["search_query"] = data

schedule_loader = ScheduleLoader(
db=db,
events_per_page=user_data["items_per_page"],
events_per_page=dialog_manager.dialog_data["events_per_page"],
search_query=dialog_manager.dialog_data.get("search_query"),
)
dialog_manager.dialog_data["pages"] = await schedule_loader.get_pages_count()
Expand All @@ -145,12 +144,11 @@ async def set_search_query(

async def reset_search(callback: CallbackQuery, button: Button, manager: DialogManager):
db: Database = manager.middleware_data["db"]
user_data = await manager.middleware_data["state"].get_data()

manager.dialog_data.pop("search_query")
schedule_loader = ScheduleLoader(
db=db,
events_per_page=user_data["items_per_page"],
events_per_page=manager.dialog_data["events_per_page"],
)
manager.dialog_data["pages"] = await schedule_loader.get_pages_count()

Expand Down
9 changes: 5 additions & 4 deletions src/bot/dialogs/schedule/subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,26 @@


async def subscriptions_getter(dialog_manager: DialogManager, db: Database, **kwargs):
user_data = await dialog_manager.middleware_data["state"].get_data()
pages = await db.subscription.get_number_of_pages(
user_data["items_per_page"],
dialog_manager.dialog_data["events_per_page"],
Subscription.user_id == dialog_manager.event.from_user.id,
)
if pages == 0:
pages = 1
current_page = await dialog_manager.find(ID_SUBSCRIPTIONS_SCROLL).get_page()
subscriptions = await db.subscription.get_page(
current_page,
user_data["items_per_page"],
dialog_manager.dialog_data["events_per_page"],
Subscription.user_id == dialog_manager.event.from_user.id,
order_by=Subscription.event_id,
)
current_event = await db.event.get_current()
return {
"pages": pages,
"subscriptions": subscriptions,
"receive_all_announcements": user_data["receive_all_announcements"],
"receive_all_announcements": await db.user.get_receive_all_announcements_setting(
dialog_manager.event.from_user.id
),
"current_event_position": current_event.real_position if current_event else 0,
}

Expand Down
7 changes: 3 additions & 4 deletions src/bot/dialogs/schedule/tools/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
from src.bot.structures import UserRole
from src.config import conf
from src.db import Database
from src.redis.global_settings import GlobalSettings

ANNOUNCEMENT_TIMEOUT = conf.bot.announcement_timeout


async def throttle_announcement(settings: GlobalSettings) -> bool:
global_timestamp = await settings.announcement_timestamp.get()
async def throttle_announcement(db: Database) -> bool:
global_timestamp = await db.settings.get_announcement_timestamp()
timestamp = time.time()
if (timestamp - global_timestamp) < ANNOUNCEMENT_TIMEOUT:
return False
else:
await settings.announcement_timestamp.set(timestamp)
await db.settings.set_announcement_timestamp(timestamp)
return True


Expand Down
2 changes: 1 addition & 1 deletion src/bot/dialogs/schedule/tools/set_next_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async def set_next_event(
return

# Таймаут рассылки анонсов
if await throttle_announcement(manager.middleware_data["settings"]):
if await throttle_announcement(db):
pass
else:
await callback.answer(strings.errors.announce_too_fast, show_alert=True)
Expand Down
37 changes: 14 additions & 23 deletions src/bot/dialogs/settings.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery
from aiogram_dialog import Dialog, DialogManager, Window
from aiogram_dialog.widgets.kbd import Button, Cancel, Counter, ManagedCounter, SwitchTo
from aiogram_dialog.widgets.text import Const, Format
from sqlalchemy import update

from src.bot.dialogs import states
from src.bot.structures import UserRole
from src.bot.ui import strings
from src.db import Database
from src.db.models import User

ID_ITEMS_PER_PAGE_INPUT = "items_per_page_input"


async def user_info_getter(dialog_manager: DialogManager, **kwargs):
user_data = await dialog_manager.middleware_data["state"].get_data()
async def user_info_getter(dialog_manager: DialogManager, db: Database, **kwargs):
user = await db.user.get(dialog_manager.event.from_user.id)
return {
"username": dialog_manager.event.from_user.username,
"user_id": dialog_manager.event.from_user.id,
"user_role": UserRole.get_role_name(user_data["user_role"]).lower(),
"items_per_page": user_data["items_per_page"],
"username": user.username,
"user_id": user.id,
"user_role": UserRole.get_role_name(user.role),
"items_per_page": user.items_per_page,
}


async def update_counter_value(
callback: CallbackQuery, button: Button, manager: DialogManager
):
user_data = await manager.middleware_data["state"].get_data()
await manager.find(ID_ITEMS_PER_PAGE_INPUT).set_value(user_data["items_per_page"])
db: Database = manager.middleware_data["db"]
await manager.find(ID_ITEMS_PER_PAGE_INPUT).set_value(
await db.user.get_items_per_page_setting(manager.event.from_user.id)
)


async def update_items_per_page(
Expand All @@ -37,18 +36,10 @@ async def update_items_per_page(
dialog_manager: DialogManager,
):
db: Database = dialog_manager.middleware_data["db"]
state: FSMContext = dialog_manager.middleware_data["state"]
user_data = await state.get_data()
if user_data["items_per_page"] != widget.get_value():
await db.session.execute(
update(User)
.where(User.id == dialog_manager.event.from_user.id)
.values(items_per_page=widget.get_value())
)
await db.session.commit()
await state.update_data(items_per_page=widget.get_value())
dialog_manager.dialog_data["items_per_page"] = widget.get_value()
await event.answer("✅ Успешно!")
await db.user.set_items_per_page_setting(
dialog_manager.event.from_user.id, int(widget.get_value())
)
await event.answer("✅ Успешно!")
await dialog_manager.switch_to(state=states.SETTINGS.MAIN)


Expand Down
Loading

0 comments on commit 46579c2

Please sign in to comment.