Files
backend/app/routes/subscription_routes.py

154 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import List
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from app.services import DatabaseManager
from instance.configdb import get_database_manager
from uuid import UUID
import logging
from sqlalchemy.exc import SQLAlchemyError
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
router = APIRouter()
class BuySubscriptionRequest(BaseModel):
telegram_id: int
plan_id: str
class SubscriptionResponse(BaseModel):
id: str
plan: str
vpn_server_id: str
expiry_date: str
created_at: str
updated_at: str
# Эндпоинт для покупки подписки
@router.post("/subscription/buy", response_model=dict)
async def buy_subscription(
request_data: BuySubscriptionRequest,
database_manager: DatabaseManager = Depends(get_database_manager)
):
"""
Покупка подписки.
"""
try:
result = await database_manager.buy_sub(request_data.telegram_id, request_data.plan_id)
if result == "ERROR":
raise HTTPException(status_code=500, detail="ERROR")
elif result == "INSUFFICIENT_FUNDS":
raise HTTPException(status_code=400, detail="INSUFFICIENT_FUNDS")
elif result == "TARIFF_NOT_FOUND":
raise HTTPException(status_code=400, detail="TARIFF_NOT_FOUND")
elif result == "ACTIVE_SUBSCRIPTION_EXISTS":
raise HTTPException(status_code=400, detail="ACTIVE_SUBSCRIPTION_EXISTS")
result = await database_manager.generate_uri(request_data.telegram_id)
return {"message": result}
except HTTPException as http_exc:
# Пропускаем HTTPException, чтобы FastAPI обработал его корректно
raise http_exc
except Exception as e:
# Обрабатываем остальные исключения
raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")
# Эндпоинт для получения последней подписки
@router.get("/subscription/{telegram_id}/last", response_model=SubscriptionResponse)
async def last_subscription(telegram_id: int, database_manager: DatabaseManager = Depends(get_database_manager)):
"""
Возвращает последнюю подписку пользователя.
"""
logger.info(f"Получение последней подписки для пользователя: {telegram_id}")
try:
subscriptions = await database_manager.get_last_subscriptions(telegram_id=telegram_id, limit=1)
if not subscriptions:
logger.warning(f"Подписки для пользователя {telegram_id} не найдены")
raise HTTPException(status_code=404, detail="No subscriptions found")
sub = subscriptions[0]
return {
"id": sub.id,
"plan": sub.plan,
"vpn_server_id": sub.vpn_server_id,
"expiry_date": sub.expiry_date.isoformat(),
"created_at": sub.created_at.isoformat(),
"updated_at": sub.updated_at.isoformat(),
}
except SQLAlchemyError as e:
logger.error(f"Ошибка базы данных при получении подписки для пользователя {telegram_id}: {e}")
raise HTTPException(status_code=500, detail="Database error")
except HTTPException as e:
# Пропускаем HTTPException, чтобы FastAPI обработал её автоматически
raise e
except Exception as e:
logger.error(f"Неожиданная ошибка: {e}")
raise HTTPException(status_code=500, detail="Internal Server Error")
@router.get("/subscriptions/{telegram_id}", response_model=List[SubscriptionResponse])
async def get_subscriptions(telegram_id: int, database_manager: DatabaseManager = Depends(get_database_manager)):
"""
Возвращает список подписок пользователя.
"""
logger.info(f"Получение подписок для пользователя: {telegram_id}")
try:
# Получаем подписки без ограничений или с указанным лимитом
subscriptions = await database_manager.get_last_subscriptions(telegram_id=telegram_id)
if not subscriptions:
logger.warning(f"Подписки для пользователя {telegram_id} не найдены")
raise HTTPException(status_code=404, detail="No subscriptions found")
# Формируем список подписок для ответа
return [
{
"id": sub.id,
"plan": sub.plan,
"vpn_server_id": sub.vpn_server_id,
"expiry_date": sub.expiry_date.isoformat(),
"created_at": sub.created_at.isoformat(),
"updated_at": sub.updated_at.isoformat(),
}
for sub in subscriptions
]
except SQLAlchemyError as e:
logger.error(f"Ошибка базы данных при получении подписок для пользователя {telegram_id}: {e}")
raise HTTPException(status_code=500, detail="Database error")
except Exception as e:
logger.error(f"Неожиданная ошибка: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/uri", response_model=dict)
async def get_uri(telegram_id: int, database_manager: DatabaseManager = Depends(get_database_manager)):
"""
Возвращает список подписок пользователя.
"""
logger.info(f"Получение подписок для пользователя: {telegram_id}")
try:
# Получаем подписки без ограничений или с указанным лимитом
uri = await database_manager.generate_uri(telegram_id)
if uri == "SUB_ERROR":
raise HTTPException(status_code=404, detail="SUB_ERROR")
if not uri:
logger.warning(f"Не удалось сгенерировать URI для пользователя с telegram_id {telegram_id}")
raise HTTPException(status_code=404, detail="URI not found")
return {"detail": uri}
except HTTPException as e:
# Пропускаем HTTPException, чтобы FastAPI обработал её автоматически
raise e
except SQLAlchemyError as e:
logger.error(f"Ошибка базы данных при получении подписок для пользователя {telegram_id}: {e}")
raise HTTPException(status_code=500, detail="Database error")
except Exception as e:
logger.error(f"Неожиданная ошибка: {e}")
raise HTTPException(status_code=500, detail=str(e))