Files
backend/app/postgresql1.py
Disledg e4be2e1811 revert bfe898f10a
revert Пиздец очередной
2024-12-21 16:29:17 +01:00

192 lines
8.4 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 flask import Flask, request, jsonify
from databases.model import User, Subscription, Transaction
from sqlalchemy.future import select
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import desc
from dateutil.relativedelta import relativedelta
from datetime import datetime
from utils.panel import PanelInteraction
from databases.mongodb import MongoDBRepository
import random
import string
import logging
import asyncio
app = Flask(__name__)
# Настройка логирования
logger = logging.getLogger(__name__)
mongo_repo = MongoDBRepository()
# Генератор сессий передаётся извне (например, через dependency injection)
session_generator = None
def generate_string(length):
"""
Генерирует случайную строку заданной длины.
"""
characters = string.ascii_lowercase + string.digits
return ''.join(random.choices(characters, k=length))
@app.route('/create_user', methods=['POST'])
def create_user():
telegram_id = request.json.get('telegram_id')
if not telegram_id:
return jsonify({'error': 'Telegram ID is required'}), 400
async def process():
async for session in session_generator():
try:
username = generate_string(6)
result = await session.execute(select(User).where(User.telegram_id == int(telegram_id)))
user = result.scalars().first()
if not user:
new_user = User(telegram_id=int(telegram_id), username=username)
session.add(new_user)
await session.commit()
return jsonify({'user': new_user.id, 'username': new_user.username}), 201
return jsonify({'user': user.id, 'username': user.username}), 200
except SQLAlchemyError as e:
logger.error(f"Ошибка при создании пользователя {telegram_id}: {e}")
await session.rollback()
return jsonify({'error': 'Internal server error'}), 500
return asyncio.run(process())
@app.route('/get_user/<int:telegram_id>', methods=['GET'])
def get_user_by_telegram_id(telegram_id):
async def process():
async for session in session_generator():
try:
result = await session.execute(select(User).where(User.telegram_id == telegram_id))
user = result.scalars().first()
if user:
return jsonify({'id': user.id, 'username': user.username, 'balance': user.balance}), 200
return jsonify({'error': 'User not found'}), 404
except SQLAlchemyError as e:
logger.error(f"Ошибка при получении пользователя {telegram_id}: {e}")
return jsonify({'error': 'Internal server error'}), 500
return asyncio.run(process())
@app.route('/update_balance', methods=['POST'])
def update_balance():
data = request.json
telegram_id = data.get('telegram_id')
amount = data.get('amount')
if not telegram_id or amount is None:
return jsonify({'error': 'Telegram ID and amount are required'}), 400
async def process():
async for session in session_generator():
try:
result = await session.execute(select(User).where(User.telegram_id == telegram_id))
user = result.scalars().first()
if user:
user.balance += int(amount)
transaction = Transaction(user_id=user.id, amount=amount)
session.add(transaction)
await session.commit()
return jsonify({'balance': user.balance}), 200
return jsonify({'error': 'User not found'}), 404
except SQLAlchemyError as e:
logger.error(f"Ошибка при обновлении баланса: {e}")
await session.rollback()
return jsonify({'error': 'Internal server error'}), 500
return asyncio.run(process())
@app.route('/buy_subscription', methods=['POST'])
def buy_subscription():
data = request.json
telegram_id = data.get('telegram_id')
plan_id = data.get('plan_id')
if not telegram_id or not plan_id:
return jsonify({'error': 'Telegram ID and Plan ID are required'}), 400
async def process():
async for session in session_generator():
try:
result = await session.execute(select(User).where(User.telegram_id == telegram_id))
user = result.scalars().first()
if not user:
return jsonify({'error': 'User not found'}), 404
plan = await mongo_repo.get_subscription_plan(plan_id)
if not plan:
return jsonify({'error': 'Plan not found'}), 404
cost = int(plan['price'])
if user.balance >= cost:
user.balance -= cost
expiry_date = datetime.utcnow() + relativedelta(months=plan['duration_months'])
server = await mongo_repo.get_server_with_least_clients()
new_subscription = Subscription(user_id=user.id, vpn_server_id=str(server['server']['name']),
plan=plan_id, expiry_date=expiry_date)
session.add(new_subscription)
await session.commit()
return jsonify({'message': 'Subscription purchased successfully'}), 200
return jsonify({'error': 'Insufficient funds'}), 400
except SQLAlchemyError as e:
logger.error(f"Ошибка при покупке подписки {plan_id} для пользователя {telegram_id}: {e}")
await session.rollback()
return jsonify({'error': 'Internal server error'}), 500
return asyncio.run(process())
@app.route('/add_to_server', methods=['POST'])
def add_to_server():
data = request.json
telegram_id = data.get('telegram_id')
if not telegram_id:
return jsonify({'error': 'Telegram ID is required'}), 400
async def process():
async for session in session_generator():
try:
result = await session.execute(select(Subscription).join(User).where(User.telegram_id == int(telegram_id)))
user_sub = result.scalars().first()
if not user_sub:
logger.error(f"Не удалось найти подписку для пользователя с Telegram ID {telegram_id}.")
return jsonify({'error': 'Subscription not found'}), 404
user_result = await session.execute(select(User).where(User.telegram_id == telegram_id))
user = user_result.scalars().first()
server = await mongo_repo.get_server(user_sub.vpn_server_id)
if not server:
logger.error(f"Не удалось найти сервер с ID {user_sub.vpn_server_id}.")
return jsonify({'error': 'Server not found'}), 404
server_info = server['server']
url_base = f"https://{server_info['ip']}:{server_info['port']}/{server_info['secretKey']}"
login_data = {
'username': server_info['login'],
'password': server_info['password'],
}
panel = PanelInteraction(url_base, login_data, logger)
expiry_date_iso = user_sub.expiry_date.isoformat()
response = await panel.add_client(user.id, expiry_date_iso, user.username)
if response == "OK":
logger.info(f"Клиент {telegram_id} успешно добавлен на сервер.")
return jsonify({'message': 'Client added successfully'}), 200
else:
logger.error(f"Ошибка при добавлении клиента {telegram_id} на сервер: {response}")
return jsonify({'error': 'Failed to add client to server'}), 500
except Exception as e:
logger.error(f"Ошибка при установке на сервер для пользователя {telegram_id}: {e}")
return jsonify({'error': 'Internal server error'}), 500
return asyncio.run(process())
if __name__ == '__main__':
app.run(debug=True)