Update project configuration and codebase

This commit is contained in:
2026-04-12 12:19:53 +07:00
parent 0ed0ad2b92
commit 0ac8ed8d64
25 changed files with 273 additions and 310 deletions

View File

@@ -1,30 +1,28 @@
from typing import Optional
from aiogram import Bot
from aiogram.types import Message, ReactionTypeEmoji
from aiogram.types import User as TelegramUser
from sqlalchemy.ext.asyncio import AsyncSession
from aiogram.types import Message, ReactionTypeEmoji, User as TelegramUser
from remnawave import RemnawaveSDK
from sqlalchemy.ext.asyncio import AsyncSession
from config import settings
from db.models.tickets import TicketStatus
from db.models.users import User
from misc import utils
from repositories import UserRepository
from repositories.tickets import TicketRepository
from schemas.subscriptions import SubscriptionPlan
from schemas.tickets import NewTicketDTO
from schemas.users import NewUserDTO, TicketCreator
from repositories import UserRepository
from repositories.tickets import TicketRepository
from services.rw import RWUserInfo, get_user_by_telegram_id
from texts import (
ADMIN_STANDARD_FALLBACK,
ADMIN_TICKET_WITH_RW,
ADMIN_TICKET_WITHOUT_RW,
SUPPORT_SIGNATURE,
TICKET_STATUS_EMOJIS,
ADMIN_TICKET_WITHOUT_RW,
)
from misc import utils
class UserServiceException(Exception): ...
class UserServiceError(Exception): ...
class UserService:
@@ -37,8 +35,8 @@ class UserService:
@staticmethod
def format_ticket_name(
creator: TicketCreator,
status: Optional[TicketStatus] = TicketStatus.OPEN,
ticket_id: Optional[int] = None,
status: TicketStatus | None = TicketStatus.OPEN,
ticket_id: int | None = None,
):
return (
TICKET_STATUS_EMOJIS[status.value]
@@ -49,7 +47,7 @@ class UserService:
@staticmethod
async def format_admin_support_message(
ticket_number: int, user: User, rw_user: Optional[RWUserInfo], balance: int
ticket_number: int, user: TelegramUser, rw_user: RWUserInfo | None, balance: int
):
username_display = utils.format_username(user.username)
@@ -65,9 +63,7 @@ class UserService:
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
)
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)
squads = utils.format_squads(rw_user.active_squads)
@@ -92,7 +88,7 @@ class UserService:
session: AsyncSession,
user_id: int,
rw_sdk: RemnawaveSDK,
referal: Optional[int] = None,
referal: int | None = None,
) -> User:
user = await self.user_repository.get_user_by_id(session, user_id)
if user:
@@ -100,9 +96,7 @@ class UserService:
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
)
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)
@@ -114,9 +108,7 @@ class UserService:
subscription: SubscriptionPlan,
bot: Bot,
):
ticket = await self.ticket_repository.get_available_ticket_by_user_id(
session, user.id
)
ticket = await self.ticket_repository.get_available_ticket_by_user_id(session, user.id)
db_user = await self.user_repository.get_user_by_id(session, user.id)
if ticket:
@@ -143,15 +135,11 @@ class UserService:
ticket_dto = NewTicketDTO(
creator_id=user.id,
)
ticket = await self.ticket_repository.create_ticket(
session, ticket_data=ticket_dto
)
ticket = await self.ticket_repository.create_ticket(session, ticket_data=ticket_dto)
thread = await bot.create_forum_topic(
settings.admin_group_id,
self.format_ticket_name(
creator, ticket_id=ticket.id, status=TicketStatus.PENDING
),
self.format_ticket_name(creator, ticket_id=ticket.id, status=TicketStatus.PENDING),
)
ticket = await self.ticket_repository.update_ticket_thread_id(
session, ticket, thread.message_thread_id
@@ -166,20 +154,16 @@ class UserService:
full_name=user.full_name,
user_id=user.id,
username=user.username,
balance=db_user,
balance=db_user.balance,
),
)
async def support_forward_message(
self, session: AsyncSession, msg: Message, rw: RemnawaveSDK
):
async def support_forward_message(self, session: AsyncSession, msg: Message, rw: RemnawaveSDK):
user = await self.user_repository.get_user_by_id(session, msg.from_user.id)
if not user:
raise UserServiceException("User %d is not found.", msg.from_user.id)
raise UserServiceError("User %d is not found.", msg.from_user.id)
ticket = await self.ticket_repository.get_available_ticket_by_user_id(
session, user.id
)
ticket = await self.ticket_repository.get_available_ticket_by_user_id(session, user.id)
if ticket:
try:
@@ -199,15 +183,11 @@ class UserService:
ticket_dto = NewTicketDTO(
creator_id=user.id,
)
ticket = await self.ticket_repository.create_ticket(
session, ticket_data=ticket_dto
)
ticket = await self.ticket_repository.create_ticket(session, ticket_data=ticket_dto)
thread = await msg.bot.create_forum_topic(
settings.admin_group_id,
self.format_ticket_name(
creator, ticket_id=ticket.id, status=TicketStatus.PENDING
),
self.format_ticket_name(creator, ticket_id=ticket.id, status=TicketStatus.PENDING),
)
ticket = await self.ticket_repository.update_ticket_thread_id(
session, ticket, thread.message_thread_id
@@ -223,26 +203,18 @@ class UserService:
balance=user.balance,
),
)
await msg.copy_to(
settings.admin_group_id, message_thread_id=thread.message_thread_id
)
await msg.copy_to(settings.admin_group_id, message_thread_id=thread.message_thread_id)
async def support_answer(self, session: AsyncSession, msg: Message):
thread_id = msg.message_thread_id
ticket = await self.ticket_repository.get_ticket_by_thread_id(
session, thread_id=thread_id
)
ticket = await self.ticket_repository.get_ticket_by_thread_id(session, thread_id=thread_id)
if ticket.status == TicketStatus.PENDING:
await self.ticket_repository.update_ticket_status(
session, ticket, TicketStatus.OPEN
)
await self.ticket_repository.update_ticket_status(session, ticket, TicketStatus.OPEN)
await msg.bot.edit_forum_topic(
settings.admin_group_id,
ticket.thread_id,
name=self.format_ticket_name(
TicketCreator(ticket.creator_id), ticket_id=ticket.id
),
name=self.format_ticket_name(TicketCreator(ticket.creator_id), ticket_id=ticket.id),
)
try:
@@ -254,9 +226,7 @@ class UserService:
async def close_ticket(self, session: AsyncSession, msg: Message):
thread_id = msg.message_thread_id
ticket = await self.ticket_repository.get_ticket_by_thread_id(
session, thread_id=thread_id
)
ticket = await self.ticket_repository.get_ticket_by_thread_id(session, thread_id=thread_id)
await msg.bot.edit_forum_topic(
settings.admin_group_id,
@@ -268,16 +238,12 @@ class UserService:
),
)
await self.ticket_repository.update_ticket_status(
session, ticket, TicketStatus.CLOSED
)
await msg.bot.close_forum_topic(
settings.admin_group_id, message_thread_id=thread_id
)
await self.ticket_repository.update_ticket_status(session, ticket, TicketStatus.CLOSED)
await msg.bot.close_forum_topic(settings.admin_group_id, message_thread_id=thread_id)
async def update_user_link(
self, session: AsyncSession, user_id: int, rw_sdk: RemnawaveSDK
) -> Optional[User]:
) -> User | None:
rw_user = await get_user_by_telegram_id(rw_sdk, user_id)
link = utils.get_subscription_link(rw_user.short_uuid)
@@ -286,22 +252,12 @@ class UserService:
return user
async def fetch_user_by_thread(
self, session: AsyncSession, thread_id: int
) -> Optional[User]:
ticket = await self.ticket_repository.get_ticket_by_thread_id(
session, thread_id=thread_id
)
async def fetch_user_by_thread(self, session: AsyncSession, thread_id: int) -> User | None:
ticket = await self.ticket_repository.get_ticket_by_thread_id(session, thread_id=thread_id)
return await self.user_repository.get_user_by_id(session, ticket.creator_id)
async def fetch_referal_by_thread(
self, session: AsyncSession, thread_id: int
) -> Optional[User]:
ticket = await self.ticket_repository.get_ticket_by_thread_id(
session, thread_id=thread_id
)
async def fetch_referal_by_thread(self, session: AsyncSession, thread_id: int) -> User | None:
ticket = await self.ticket_repository.get_ticket_by_thread_id(session, thread_id=thread_id)
return await self.user_repository.get_referal_by_user_id(
session, ticket.creator_id
)
return await self.user_repository.get_referal_by_user_id(session, ticket.creator_id)