mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-02-06 12:10:25 +00:00
287 lines
9.5 KiB
Python
287 lines
9.5 KiB
Python
import logging
|
||
from datetime import datetime
|
||
from typing import Optional
|
||
from sqlalchemy import select, update, func
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.database.models import User, WelcomeText
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
WELCOME_TEXT_KEY = "welcome_text"
|
||
|
||
async def get_active_welcome_text(db: AsyncSession) -> Optional[str]:
|
||
result = await db.execute(
|
||
select(WelcomeText)
|
||
.where(WelcomeText.is_active == True)
|
||
.where(WelcomeText.is_enabled == True)
|
||
.order_by(WelcomeText.updated_at.desc())
|
||
)
|
||
welcome_text = result.scalar_one_or_none()
|
||
|
||
if welcome_text:
|
||
return welcome_text.text_content
|
||
|
||
return None
|
||
|
||
async def get_current_welcome_text_settings(db: AsyncSession) -> dict:
|
||
result = await db.execute(
|
||
select(WelcomeText)
|
||
.where(WelcomeText.is_active == True)
|
||
.order_by(WelcomeText.updated_at.desc())
|
||
)
|
||
welcome_text = result.scalar_one_or_none()
|
||
|
||
if welcome_text:
|
||
return {
|
||
'text': welcome_text.text_content,
|
||
'is_enabled': welcome_text.is_enabled,
|
||
'id': welcome_text.id
|
||
}
|
||
|
||
return {
|
||
'text': await get_current_welcome_text_or_default(),
|
||
'is_enabled': True,
|
||
'id': None
|
||
}
|
||
|
||
|
||
async def get_welcome_text_by_id(db: AsyncSession, welcome_text_id: int) -> Optional[WelcomeText]:
|
||
result = await db.execute(
|
||
select(WelcomeText).where(WelcomeText.id == welcome_text_id)
|
||
)
|
||
return result.scalar_one_or_none()
|
||
|
||
|
||
async def list_welcome_texts(
|
||
db: AsyncSession,
|
||
*,
|
||
include_inactive: bool = True,
|
||
limit: int = 50,
|
||
offset: int = 0,
|
||
):
|
||
query = select(WelcomeText).order_by(WelcomeText.updated_at.desc())
|
||
if not include_inactive:
|
||
query = query.where(WelcomeText.is_active == True)
|
||
|
||
result = await db.execute(query.limit(limit).offset(offset))
|
||
return result.scalars().all()
|
||
|
||
|
||
async def count_welcome_texts(db: AsyncSession, *, include_inactive: bool = True) -> int:
|
||
query = select(func.count(WelcomeText.id))
|
||
if not include_inactive:
|
||
query = query.where(WelcomeText.is_active == True)
|
||
|
||
result = await db.execute(query)
|
||
return result.scalar()
|
||
|
||
async def toggle_welcome_text_status(db: AsyncSession, admin_id: int) -> bool:
|
||
try:
|
||
result = await db.execute(
|
||
select(WelcomeText)
|
||
.where(WelcomeText.is_active == True)
|
||
.order_by(WelcomeText.updated_at.desc())
|
||
)
|
||
welcome_text = result.scalar_one_or_none()
|
||
|
||
if welcome_text:
|
||
welcome_text.is_enabled = not welcome_text.is_enabled
|
||
welcome_text.updated_at = datetime.utcnow()
|
||
|
||
await db.commit()
|
||
await db.refresh(welcome_text)
|
||
|
||
status = "включен" if welcome_text.is_enabled else "отключен"
|
||
logger.info(f"Приветственный текст {status} администратором {admin_id}")
|
||
return welcome_text.is_enabled
|
||
else:
|
||
default_text = await get_current_welcome_text_or_default()
|
||
new_welcome_text = WelcomeText(
|
||
text_content=default_text,
|
||
is_active=True,
|
||
is_enabled=True,
|
||
created_by=admin_id
|
||
)
|
||
|
||
db.add(new_welcome_text)
|
||
await db.commit()
|
||
await db.refresh(new_welcome_text)
|
||
|
||
logger.info(f"Создан и включен дефолтный приветственный текст администратором {admin_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при переключении статуса приветственного текста: {e}")
|
||
await db.rollback()
|
||
return False
|
||
|
||
async def set_welcome_text(db: AsyncSession, text_content: str, admin_id: int) -> bool:
|
||
try:
|
||
current_settings = await get_current_welcome_text_settings(db)
|
||
current_enabled_status = current_settings.get('is_enabled', True)
|
||
|
||
await db.execute(
|
||
update(WelcomeText).values(is_active=False)
|
||
)
|
||
|
||
new_welcome_text = WelcomeText(
|
||
text_content=text_content,
|
||
is_active=True,
|
||
is_enabled=current_enabled_status,
|
||
created_by=admin_id
|
||
)
|
||
|
||
db.add(new_welcome_text)
|
||
await db.commit()
|
||
await db.refresh(new_welcome_text)
|
||
|
||
logger.info(f"Установлен новый приветственный текст администратором {admin_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при установке приветственного текста: {e}")
|
||
await db.rollback()
|
||
return False
|
||
|
||
|
||
async def create_welcome_text(
|
||
db: AsyncSession,
|
||
*,
|
||
text_content: str,
|
||
created_by: Optional[int] = None,
|
||
is_enabled: bool = True,
|
||
is_active: bool = True,
|
||
) -> WelcomeText:
|
||
resolved_creator = created_by
|
||
|
||
if created_by is not None:
|
||
result = await db.execute(select(User.id).where(User.id == created_by))
|
||
resolved_creator = result.scalar_one_or_none()
|
||
|
||
if is_active:
|
||
await db.execute(update(WelcomeText).values(is_active=False))
|
||
|
||
welcome_text = WelcomeText(
|
||
text_content=text_content,
|
||
is_active=is_active,
|
||
is_enabled=is_enabled,
|
||
created_by=resolved_creator,
|
||
)
|
||
|
||
db.add(welcome_text)
|
||
await db.commit()
|
||
await db.refresh(welcome_text)
|
||
|
||
logger.info(
|
||
"✅ Создан приветственный текст ID %s (активный=%s, включен=%s)",
|
||
welcome_text.id,
|
||
welcome_text.is_active,
|
||
welcome_text.is_enabled,
|
||
)
|
||
return welcome_text
|
||
|
||
|
||
async def update_welcome_text(
|
||
db: AsyncSession,
|
||
welcome_text: WelcomeText,
|
||
*,
|
||
text_content: Optional[str] = None,
|
||
is_enabled: Optional[bool] = None,
|
||
is_active: Optional[bool] = None,
|
||
) -> WelcomeText:
|
||
if is_active:
|
||
await db.execute(
|
||
update(WelcomeText)
|
||
.where(WelcomeText.id != welcome_text.id)
|
||
.values(is_active=False)
|
||
)
|
||
|
||
if text_content is not None:
|
||
welcome_text.text_content = text_content
|
||
|
||
if is_enabled is not None:
|
||
welcome_text.is_enabled = is_enabled
|
||
|
||
if is_active is not None:
|
||
welcome_text.is_active = is_active
|
||
|
||
welcome_text.updated_at = datetime.utcnow()
|
||
|
||
await db.commit()
|
||
await db.refresh(welcome_text)
|
||
|
||
logger.info(
|
||
"📝 Обновлен приветственный текст ID %s (активный=%s, включен=%s)",
|
||
welcome_text.id,
|
||
welcome_text.is_active,
|
||
welcome_text.is_enabled,
|
||
)
|
||
return welcome_text
|
||
|
||
|
||
async def delete_welcome_text(db: AsyncSession, welcome_text: WelcomeText) -> None:
|
||
await db.delete(welcome_text)
|
||
await db.commit()
|
||
logger.info("🗑️ Удален приветственный текст ID %s", welcome_text.id)
|
||
|
||
async def get_current_welcome_text_or_default() -> str:
|
||
return (
|
||
f"Привет, {{user_name}}! 🎁 3 дней VPN бесплатно! "
|
||
f"Подключайтесь за минуту и забудьте о блокировках. "
|
||
f"✅ До 1 Гбит/с скорость "
|
||
f"✅ Умный VPN — можно не отключать для большинства российских сервисов "
|
||
f"✅ Современные протоколы — максимум защиты и анонимности "
|
||
f"💉 Всего 99₽/мес за 1 устройство "
|
||
f"👇 Жмите кнопку и подключайтесь!"
|
||
)
|
||
|
||
def replace_placeholders(text: str, user) -> str:
|
||
first_name = getattr(user, 'first_name', None)
|
||
username = getattr(user, 'username', None)
|
||
|
||
first_name = first_name.strip() if first_name else None
|
||
username = username.strip() if username else None
|
||
|
||
user_name = first_name or username or "друг"
|
||
display_first_name = first_name or "друг"
|
||
display_username = f"@{username}" if username else (first_name or "друг")
|
||
clean_username = username or first_name or "друг"
|
||
|
||
replacements = {
|
||
'{user_name}': user_name,
|
||
'{first_name}': display_first_name,
|
||
'{username}': display_username,
|
||
'{username_clean}': clean_username,
|
||
'Egor': user_name
|
||
}
|
||
|
||
result = text
|
||
for placeholder, value in replacements.items():
|
||
result = result.replace(placeholder, value)
|
||
|
||
return result
|
||
|
||
async def get_welcome_text_for_user(db: AsyncSession, user) -> str:
|
||
welcome_text = await get_active_welcome_text(db)
|
||
|
||
if not welcome_text:
|
||
return None
|
||
|
||
if isinstance(user, str):
|
||
class SimpleUser:
|
||
def __init__(self, name):
|
||
self.first_name = name
|
||
self.username = None
|
||
user = SimpleUser(user)
|
||
|
||
return replace_placeholders(welcome_text, user)
|
||
|
||
def get_available_placeholders() -> dict:
|
||
return {
|
||
'{user_name}': 'Имя или username пользователя (приоритет: имя → username → "друг")',
|
||
'{first_name}': 'Только имя пользователя (или "друг" если не указано)',
|
||
'{username}': 'Username с символом @ (или имя если username не указан)',
|
||
'{username_clean}': 'Username без символа @ (или имя если username не указан)'
|
||
}
|