import logging from aiogram.types import Message from remnawave import RemnawaveSDK from sqlalchemy.ext.asyncio import AsyncSession from bot.texts import ( NO_SUBSCRIPTION, NOTHING_PLACEHOLDER, SUBSCRIPTION_INFORMATION, ) from db.models.users import User from misc import utils from repositories import UserRepository from schemas.users import NewUserDTO from services.rw import RWUserInfo, get_user_by_telegram_id logger = logging.getLogger(__name__) class UserServiceError(Exception): ... class UserService: def __init__(self, user_repository: UserRepository) -> None: self.user_repository = user_repository @staticmethod def format_subscription_message( rw_user: RWUserInfo | None, link: str | None = None, ): if rw_user is None: # Пользователь не найден в Remnawave return NO_SUBSCRIPTION status_icon, status_text = utils.format_status(rw_user.status) expire_date = rw_user.expire_at.strftime("%d.%m.%Y") days_left = utils.format_days_left(rw_user.expire_at) used_traffic = utils.format_traffic(rw_user.used_traffic_bytes, rw_user.traffic_limit_bytes) hwid_limit = utils.format_hwid_limit(rw_user.hwid_device_limit) link = link or NOTHING_PLACEHOLDER return SUBSCRIPTION_INFORMATION.format( status_icon=status_icon, status=status_text, expire_date=expire_date, days_left=days_left, used_traffic=used_traffic, hwid_limit=hwid_limit, link=link, ) async def add_user( self, session: AsyncSession, user_id: int, rw_sdk: RemnawaveSDK, referal: int | None = None, ) -> User: user = await self.user_repository.get_user_by_id(session, user_id) if user: return user rw_user = await get_user_by_telegram_id(rw_sdk, user_id) link = utils.get_subscription_link(rw_user.short_uuid) if rw_user else None referal = int(referal) if str(referal).isdigit() and user_id != int(referal) else None model = NewUserDTO(id=user_id, referal=referal, link=link) return await self.user_repository.create_user(session, model) async def update_user_link( self, session: AsyncSession, user_id: int, rw_sdk: RemnawaveSDK ) -> User | None: rw_user = await get_user_by_telegram_id(rw_sdk, user_id) user = await self.user_repository.get_user_by_id(session, user_id) if not rw_user: return user link = utils.get_subscription_link(rw_user.short_uuid) user = await self.user_repository.update_user_link(session, user_id, link) return user async def send_promotion_to_users(self, session: AsyncSession, msg: Message) -> list[User]: users = await self.user_repository.get_users(session) sent: list[User] = [] for user in users: try: await msg.copy_to(user.id) sent.append(user) except Exception: logger.critical("failed to send a message to user %d.", user.id, exc_info=True) return sent