Initial commit: VPN Telegram bot (sanitized defaults)
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
"""Пробный период подписки."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from remnawave import RemnawaveSDK
|
||||
|
||||
from services.db import AuthError, Database
|
||||
from services.purchase import provision_subscription
|
||||
from services.tariffs import Tariff, get_tariff
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_TRIAL_DAYS = 3
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class TrialResult:
|
||||
ok: bool
|
||||
message: str
|
||||
expire_at: datetime | None = None
|
||||
|
||||
|
||||
def trial_days_setting(db: Database) -> int:
|
||||
raw = (db.get_setting("trial_days") or str(DEFAULT_TRIAL_DAYS)).strip()
|
||||
try:
|
||||
days = int(raw)
|
||||
except ValueError:
|
||||
days = DEFAULT_TRIAL_DAYS
|
||||
return max(0, min(days, 30))
|
||||
|
||||
|
||||
def trial_enabled(db: Database) -> bool:
|
||||
return trial_days_setting(db) > 0
|
||||
|
||||
|
||||
async def grant_trial(
|
||||
*,
|
||||
db: Database,
|
||||
sdk: RemnawaveSDK,
|
||||
telegram_id: int,
|
||||
tariffs: list[Tariff],
|
||||
) -> TrialResult:
|
||||
days = trial_days_setting(db)
|
||||
if days <= 0:
|
||||
return TrialResult(ok=False, message="Пробный период выключен")
|
||||
|
||||
user = db.ensure_user(telegram_id)
|
||||
if user.banned:
|
||||
return TrialResult(ok=False, message="Аккаунт заблокирован")
|
||||
if user.trial_used_at:
|
||||
return TrialResult(ok=False, message="Пробный период уже использован")
|
||||
|
||||
tariff_id = (db.get_setting("trial_tariff_id") or "").strip()
|
||||
tariff = get_tariff(tariffs, tariff_id) if tariff_id else None
|
||||
if tariff is None and tariffs:
|
||||
tariff = min(tariffs, key=lambda t: t.price)
|
||||
if tariff is None:
|
||||
return TrialResult(ok=False, message="Нет тарифа для пробного периода")
|
||||
|
||||
trial_tariff = Tariff(
|
||||
id=tariff.id,
|
||||
title=f"Trial · {tariff.title}",
|
||||
price=0.0,
|
||||
days=days,
|
||||
traffic_gb=tariff.traffic_gb,
|
||||
device_limit=tariff.device_limit,
|
||||
squad_uuids=tariff.squad_uuids,
|
||||
description="trial",
|
||||
)
|
||||
|
||||
try:
|
||||
rw_uuid, sub_url, expire_at = await provision_subscription(
|
||||
sdk,
|
||||
telegram_id=telegram_id,
|
||||
tariff=trial_tariff,
|
||||
login=user.login,
|
||||
extra_devices=user.extra_devices,
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.exception("trial provision failed")
|
||||
return TrialResult(ok=False, message=f"Не удалось выдать пробный период: {exc}")
|
||||
|
||||
db.mark_trial_used(telegram_id)
|
||||
db.record_purchase(
|
||||
telegram_id,
|
||||
tariff_id=f"trial:{tariff.id}",
|
||||
price=0.0,
|
||||
remnawave_uuid=rw_uuid,
|
||||
subscription_url=sub_url,
|
||||
)
|
||||
return TrialResult(
|
||||
ok=True,
|
||||
message=f"Пробный период на {days} дн. активен до {expire_at.strftime('%d.%m.%Y %H:%M UTC')}",
|
||||
expire_at=expire_at,
|
||||
)
|
||||
Reference in New Issue
Block a user