Files
malenia/bot/handlers/client/menus.py
2026-06-16 16:24:02 +07:00

214 lines
6.8 KiB
Python

from aiogram import F, Router
from aiogram.filters import Command, CommandObject, CommandStart
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
from sqlalchemy.ext.asyncio import AsyncSession
from bot.keyboards.client import close_kb, construct_devices_list, main_menu, subscription_controls
from bot.keyboards.common import return_to_menu
from bot.texts import (
CALLBACK_FALLBACK,
FAQ_TEXT,
GENERAL_PROCESSING,
NO_CONNECTIONS,
NO_SUBSCRIPTION,
)
from db.models.users import User
from misc import utils
from misc.utils import build_main_menu_text, format_subscription_link
from schemas.di import DependenciesDTO
from schemas.subscriptions import InternalSquads, SubscriptionPlan
from services.rw import get_hwid_list, get_user_by_telegram_id
router = Router()
@router.message(CommandStart(deep_link=True, deep_link_encoded=True))
async def fetch_referal(
msg: Message,
command: CommandObject,
state: FSMContext,
session: AsyncSession,
deps: DependenciesDTO,
):
await state.clear()
data = command.args.split("_")
if not data:
await standard_start(msg, state, session, deps)
return
referal = int(data[1])
user = await deps.user_service.add_user(
session, user_id=msg.from_user.id, referal=referal, rw_sdk=deps.rw_sdk
)
await msg.answer(
build_main_menu_text(
format_subscription_link(user.subscription_link), balance=user.balance
),
reply_markup=main_menu,
)
@router.message(Command(commands=["start", "cancel"]))
async def standard_start(
msg: Message,
state: FSMContext,
session: AsyncSession,
deps: DependenciesDTO,
):
await state.clear()
user = await deps.user_service.add_user(session, user_id=msg.from_user.id, rw_sdk=deps.rw_sdk)
await msg.answer(
build_main_menu_text(
format_subscription_link(user.subscription_link), balance=user.balance
),
reply_markup=main_menu,
)
@router.callback_query(F.data == "menu:main")
async def main_menu_cb(
cb: CallbackQuery, state: FSMContext, session: AsyncSession, deps: DependenciesDTO
):
await state.clear()
user = await deps.user_repository.get_user_by_id(session, cb.from_user.id)
await cb.message.edit_text(
build_main_menu_text(
format_subscription_link(user.subscription_link), balance=user.balance
),
reply_markup=main_menu,
)
@router.callback_query(F.data == "update_link")
async def update_link(
cb: CallbackQuery, state: FSMContext, session: AsyncSession, deps: DependenciesDTO
):
await state.clear()
await cb.message.edit_text(GENERAL_PROCESSING)
user = await deps.user_service.update_user_link(session, cb.from_user.id, deps.rw_sdk)
await cb.answer("")
await cb.message.edit_text(
build_main_menu_text(
format_subscription_link(user.subscription_link), balance=user.balance
),
reply_markup=main_menu,
)
@router.callback_query(F.data == "faq")
async def faq(cb: CallbackQuery, state: FSMContext):
await state.clear()
await cb.message.edit_text(FAQ_TEXT, reply_markup=return_to_menu)
@router.callback_query(F.data == "sub_info")
async def sub_info(
cb: CallbackQuery, state: FSMContext, deps: DependenciesDTO, session: AsyncSession
):
await state.clear()
await cb.message.edit_text(GENERAL_PROCESSING, reply_markup=close_kb)
rw_user = await get_user_by_telegram_id(deps.rw_sdk, cb.from_user.id)
user: User | None = await deps.user_service.update_user_link(
session, cb.from_user.id, deps.rw_sdk
)
sub = await deps.subscriptions_repository.get_subscription_by_user_id(session, cb.from_user.id)
if not rw_user:
await cb.message.edit_text(NO_SUBSCRIPTION, reply_markup=return_to_menu)
return
if not user:
await cb.answer(CALLBACK_FALLBACK)
return
if rw_user and not sub:
try:
dto = SubscriptionPlan(
devices=rw_user.hwid_device_limit,
whitelists=bool(rw_user.active_squads.count(InternalSquads.WHITELISTS)),
discount=0,
)
sub = await deps.subscriptions_repository.create_subscription(
session,
user_id=user.id,
end_date=rw_user.expire_at,
devices=rw_user.hwid_device_limit,
duration_days=30,
whitelists=dto.whitelists,
plan_price_paid=utils.calculate_price(dto),
)
except Exception:
await cb.answer(CALLBACK_FALLBACK)
return
await cb.message.edit_text(
deps.user_service.format_subscription_message(
rw_user, link=user.subscription_link, autorenew=sub.autorenew
),
reply_markup=subscription_controls(
show_autorenew=bool(rw_user), current_autorenewal_status=sub.autorenew
),
)
@router.callback_query(F.data == "hwid_control")
async def hwid_control(cb: CallbackQuery, state: FSMContext, deps: DependenciesDTO):
await state.clear()
await cb.message.edit_text(GENERAL_PROCESSING, reply_markup=close_kb)
rw_user = await get_user_by_telegram_id(deps.rw_sdk, cb.from_user.id)
if not rw_user:
await cb.message.edit_text(NO_SUBSCRIPTION, reply_markup=return_to_menu)
return
devices = await get_hwid_list(deps.rw_sdk, rw_user.uuid)
if not devices:
await cb.message.edit_text(NO_CONNECTIONS, reply_markup=return_to_menu)
return
await cb.message.edit_text(text="pepe", reply_markup=construct_devices_list(devices))
@router.callback_query(F.data == "toggle:autorenewal")
async def toggle_autorenewal(
cb: CallbackQuery, state: FSMContext, session: AsyncSession, deps: DependenciesDTO
):
await state.clear()
await cb.message.edit_text(GENERAL_PROCESSING)
sub = await deps.subscriptions_repository.get_subscription_by_user_id(session, cb.from_user.id)
if not sub:
await cb.answer(CALLBACK_FALLBACK)
return
new_autorenew = not sub.autorenew
sub = await deps.subscriptions_repository.update_subscription_autorenew(
session, sub.user_id, new_autorenew
)
rw_user = await get_user_by_telegram_id(deps.rw_sdk, cb.from_user.id)
user: User | None = await deps.user_service.update_user_link(
session, cb.from_user.id, deps.rw_sdk
)
status_text = "включено" if new_autorenew else "отключено"
await cb.answer(f"Автопродление {status_text}")
await cb.message.edit_text(
deps.user_service.format_subscription_message(
rw_user, link=user.subscription_link, autorenew=sub.autorenew
),
reply_markup=subscription_controls(
show_autorenew=bool(rw_user), current_autorenewal_status=sub.autorenew
),
)