feat(subs): UNFINISHED hwid control

This commit is contained in:
agony
2026-06-16 16:24:02 +07:00
parent 7ab2293fe2
commit edfe1e6874
6 changed files with 55 additions and 7 deletions

2
.gitignore vendored
View File

@@ -175,3 +175,5 @@ cython_debug/
# PyPI configuration file # PyPI configuration file
.pypirc .pypirc
plans

View File

@@ -4,12 +4,13 @@ from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message from aiogram.types import CallbackQuery, Message
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from bot.keyboards.client import close_kb, main_menu, subscription_controls from bot.keyboards.client import close_kb, construct_devices_list, main_menu, subscription_controls
from bot.keyboards.common import return_to_menu from bot.keyboards.common import return_to_menu
from bot.texts import ( from bot.texts import (
CALLBACK_FALLBACK, CALLBACK_FALLBACK,
FAQ_TEXT, FAQ_TEXT,
GENERAL_PROCESSING, GENERAL_PROCESSING,
NO_CONNECTIONS,
NO_SUBSCRIPTION, NO_SUBSCRIPTION,
) )
from db.models.users import User from db.models.users import User
@@ -17,7 +18,7 @@ from misc import utils
from misc.utils import build_main_menu_text, format_subscription_link from misc.utils import build_main_menu_text, format_subscription_link
from schemas.di import DependenciesDTO from schemas.di import DependenciesDTO
from schemas.subscriptions import InternalSquads, SubscriptionPlan from schemas.subscriptions import InternalSquads, SubscriptionPlan
from services.rw import get_user_by_telegram_id from services.rw import get_hwid_list, get_user_by_telegram_id
router = Router() router = Router()
@@ -34,7 +35,7 @@ async def fetch_referal(
data = command.args.split("_") data = command.args.split("_")
if not data: if not data:
await standard_start(msg, command, state) await standard_start(msg, state, session, deps)
return return
referal = int(data[1]) referal = int(data[1])
@@ -126,7 +127,7 @@ async def sub_info(
return return
if not user: if not user:
await cb.answer("1" + CALLBACK_FALLBACK) await cb.answer(CALLBACK_FALLBACK)
return return
if rw_user and not sub: if rw_user and not sub:
@@ -146,7 +147,7 @@ async def sub_info(
plan_price_paid=utils.calculate_price(dto), plan_price_paid=utils.calculate_price(dto),
) )
except Exception: except Exception:
await cb.answer("2" + CALLBACK_FALLBACK) await cb.answer(CALLBACK_FALLBACK)
return return
await cb.message.edit_text( await cb.message.edit_text(
@@ -158,6 +159,25 @@ async def sub_info(
), ),
) )
@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") @router.callback_query(F.data == "toggle:autorenewal")
async def toggle_autorenewal( async def toggle_autorenewal(

View File

@@ -1,5 +1,6 @@
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder from aiogram.utils.keyboard import InlineKeyboardBuilder
from remnawave.models.hwid import HwidDeviceDto
from config import settings from config import settings
from misc.utils import convert_duration_to_int from misc.utils import convert_duration_to_int
@@ -63,6 +64,7 @@ def subscription_controls(
) )
builder.row(InlineKeyboardButton(text=autorenewal_text, callback_data="toggle:autorenewal")) builder.row(InlineKeyboardButton(text=autorenewal_text, callback_data="toggle:autorenewal"))
builder.row(InlineKeyboardButton(text="Управление устройствами", callback_data="hwid_control"))
builder.row(_return_to_menu_btn) builder.row(_return_to_menu_btn)
return builder.as_markup() return builder.as_markup()
@@ -143,3 +145,11 @@ def pay_url(url: str) -> InlineKeyboardMarkup:
[InlineKeyboardButton(text="", callback_data="menu:main")], [InlineKeyboardButton(text="", callback_data="menu:main")],
] ]
).as_markup() ).as_markup()
def construct_devices_list(devices: list[HwidDeviceDto]) -> InlineKeyboardMarkup:
builder = InlineKeyboardBuilder()
for device in devices:
builder.row(InlineKeyboardButton(text=f"{device.platform} | {device.device_model} | {device.user_agent.split('/')[0]}", callback_data=f"hwid:{device.hwid}"))
builder.row(_return_btn(data="sub_info"))
return builder.as_markup()

View File

@@ -155,6 +155,7 @@ SUBSCRIPTION_INFORMATION = (
NO_SUBSCRIPTION = f"{MALENIA_WARN} <b>Подписка не найдена.</b>" NO_SUBSCRIPTION = f"{MALENIA_WARN} <b>Подписка не найдена.</b>"
NO_CONNECTIONS = f"{MALENIA_SHIELD} <b>Вы ещё не подключались по своей ссылке.</b>"
# ============================================================ # ============================================================
# РЕФЕРАЛЬНАЯ СИСТЕМА # РЕФЕРАЛЬНАЯ СИСТЕМА

View File

@@ -1,10 +1,12 @@
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
from typing import List
from uuid import UUID from uuid import UUID
from remnawave import RemnawaveSDK from remnawave import RemnawaveSDK
from remnawave.models import CreateUserRequestDto, UpdateUserRequestDto from remnawave.models import CreateUserRequestDto, UpdateUserRequestDto
from remnawave.models.hwid import HwidDeviceDto
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -349,3 +351,15 @@ async def create_user(
except Exception as exc: except Exception as exc:
logger.warning("Failed to create user username=%s: %s", username, exc) logger.warning("Failed to create user username=%s: %s", username, exc)
return None return None
async def get_hwid_list(
sdk: RemnawaveSDK,
user_uuid: str
) -> List[HwidDeviceDto] | None:
try:
resp = await sdk.hwid.get_hwid_user(user_uuid)
return resp.devices
except Exception as exc:
logger.exception("failed to fetch hwid list for user=%s", user_uuid)
return

View File

@@ -2,8 +2,9 @@ import datetime
import logging import logging
import math import math
from aiogram.types import Message, User as TelegramUser from aiogram.types import InlineKeyboardMarkup, Message, User as TelegramUser
from remnawave import RemnawaveSDK from remnawave import RemnawaveSDK
from remnawave.models.hwid import HwidDeviceDto
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from bot.texts import NO_SUBSCRIPTION, NOTHING_PLACEHOLDER, SUBSCRIPTION_INFORMATION from bot.texts import NO_SUBSCRIPTION, NOTHING_PLACEHOLDER, SUBSCRIPTION_INFORMATION