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

4
.gitignore vendored
View File

@@ -174,4 +174,6 @@ cython_debug/
.ruff_cache/
# 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 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.texts import (
CALLBACK_FALLBACK,
FAQ_TEXT,
GENERAL_PROCESSING,
NO_CONNECTIONS,
NO_SUBSCRIPTION,
)
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 schemas.di import DependenciesDTO
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()
@@ -34,7 +35,7 @@ async def fetch_referal(
data = command.args.split("_")
if not data:
await standard_start(msg, command, state)
await standard_start(msg, state, session, deps)
return
referal = int(data[1])
@@ -126,7 +127,7 @@ async def sub_info(
return
if not user:
await cb.answer("1" + CALLBACK_FALLBACK)
await cb.answer(CALLBACK_FALLBACK)
return
if rw_user and not sub:
@@ -146,7 +147,7 @@ async def sub_info(
plan_price_paid=utils.calculate_price(dto),
)
except Exception:
await cb.answer("2" + CALLBACK_FALLBACK)
await cb.answer(CALLBACK_FALLBACK)
return
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")
async def toggle_autorenewal(

View File

@@ -1,5 +1,6 @@
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from remnawave.models.hwid import HwidDeviceDto
from config import settings
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="Управление устройствами", callback_data="hwid_control"))
builder.row(_return_to_menu_btn)
return builder.as_markup()
@@ -143,3 +145,11 @@ def pay_url(url: str) -> InlineKeyboardMarkup:
[InlineKeyboardButton(text="", callback_data="menu:main")],
]
).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_CONNECTIONS = f"{MALENIA_SHIELD} <b>Вы ещё не подключались по своей ссылке.</b>"
# ============================================================
# РЕФЕРАЛЬНАЯ СИСТЕМА

View File

@@ -1,10 +1,12 @@
import logging
from dataclasses import dataclass
from datetime import UTC, datetime, timedelta
from typing import List
from uuid import UUID
from remnawave import RemnawaveSDK
from remnawave.models import CreateUserRequestDto, UpdateUserRequestDto
from remnawave.models.hwid import HwidDeviceDto
logger = logging.getLogger(__name__)
@@ -349,3 +351,15 @@ async def create_user(
except Exception as exc:
logger.warning("Failed to create user username=%s: %s", username, exc)
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 math
from aiogram.types import Message, User as TelegramUser
from aiogram.types import InlineKeyboardMarkup, Message, User as TelegramUser
from remnawave import RemnawaveSDK
from remnawave.models.hwid import HwidDeviceDto
from sqlalchemy.ext.asyncio import AsyncSession
from bot.texts import NO_SUBSCRIPTION, NOTHING_PLACEHOLDER, SUBSCRIPTION_INFORMATION