исправление ошибки в моих ключах
This commit is contained in:
@@ -8,7 +8,7 @@ storage = MemoryStorage()
|
||||
dp = Dispatcher(bot=bot, storage=storage)
|
||||
router = Router()
|
||||
|
||||
from handlers import start, profile, keys, stats, expiry, balance, pay
|
||||
from handlers import start, profile, keys, balance, pay
|
||||
from key_management import router as key_management_router
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ from key_management import router as key_management_router
|
||||
dp.include_router(start.router)
|
||||
dp.include_router(profile.router)
|
||||
dp.include_router(keys.router)
|
||||
dp.include_router(stats.router)
|
||||
dp.include_router(expiry.router)
|
||||
dp.include_router(balance.router)
|
||||
dp.include_router(key_management_router)
|
||||
dp.include_router(pay.router)
|
||||
|
||||
@@ -9,10 +9,8 @@ import aiosqlite
|
||||
def add_client(session, client_id: str, email: str, tg_id: str, limit_ip: int, total_gb: int, expiry_time: int, enable: bool, flow: str):
|
||||
url = 'https://solonet.pocomacho.ru:62553/solonet/panel/api/inbounds/addClient'
|
||||
|
||||
# Преобразуем email в нижний регистр
|
||||
email = email.lower()
|
||||
|
||||
# Формируем данные клиента
|
||||
client_data = {
|
||||
"id": client_id,
|
||||
"alterId": 0,
|
||||
@@ -26,22 +24,19 @@ def add_client(session, client_id: str, email: str, tg_id: str, limit_ip: int, t
|
||||
"flow": flow,
|
||||
}
|
||||
|
||||
# Преобразуем данные клиента в строку JSON
|
||||
settings = json.dumps({"clients": [client_data]})
|
||||
|
||||
# Формируем тело запроса
|
||||
data = {
|
||||
"id": 1, # Если id динамически изменяется, замените это значение
|
||||
"id": 1,
|
||||
"settings": settings
|
||||
}
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json', # Если требуется токен авторизации
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
response = session.post(url, json=data, headers=headers)
|
||||
|
||||
# Выводим информацию о запросе и ответе
|
||||
print(f"Запрос на добавление клиента: {data}")
|
||||
print(f"Статус ответа: {response.status_code}")
|
||||
print(f"Ответ от сервера: {response.text}")
|
||||
@@ -51,10 +46,7 @@ def add_client(session, client_id: str, email: str, tg_id: str, limit_ip: int, t
|
||||
else:
|
||||
print(f"Ошибка при добавлении клиента: {response.status_code}, {response.text}")
|
||||
|
||||
import json
|
||||
|
||||
def extend_client_key(session, tg_id, client_id, email: str, new_expiry_time: int) -> bool:
|
||||
# Получаем текущие данные клиента
|
||||
response = session.get(f"https://solonet.pocomacho.ru:62553/solonet/panel/api/inbounds/getClientTraffics/{email}")
|
||||
print(f"GET {response.url} Status: {response.status_code}")
|
||||
print(f"GET Response: {response.text}")
|
||||
@@ -70,25 +62,21 @@ def extend_client_key(session, tg_id, client_id, email: str, new_expiry_time: in
|
||||
print("Не удалось получить данные клиента.")
|
||||
return False
|
||||
|
||||
# Получаем текущий срок действия
|
||||
current_expiry_time = client_data.get('expiryTime', 0)
|
||||
|
||||
# Если нет текущего срока, используем новый срок
|
||||
if current_expiry_time == 0:
|
||||
current_expiry_time = new_expiry_time
|
||||
|
||||
# Определяем новый срок окончания
|
||||
updated_expiry_time = max(current_expiry_time, new_expiry_time)
|
||||
|
||||
# Формируем данные для обновления
|
||||
payload = {
|
||||
"id": 1, # Если id динамически изменяется, замените это значение
|
||||
"id": 1,
|
||||
"settings": json.dumps({
|
||||
"clients": [
|
||||
{
|
||||
"id": client_id,
|
||||
"alterId": 0,
|
||||
"email": email.lower(), # Приведение email к нижнему регистру
|
||||
"email": email.lower(),
|
||||
"limitIp": 2,
|
||||
"totalGB": 429496729600000,
|
||||
"expiryTime": updated_expiry_time,
|
||||
@@ -117,6 +105,22 @@ def extend_client_key(session, tg_id, client_id, email: str, new_expiry_time: in
|
||||
else:
|
||||
print(f"Ошибка при продлении ключа: {response.status_code} - {response.text}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Ошибка запроса: {e}")
|
||||
return False
|
||||
|
||||
def delete_client(session, client_id: str) -> bool:
|
||||
url = f"https://solonet.pocomacho.ru:62553/solonet/panel/api/inbounds/1/delClient/{client_id}"
|
||||
headers = {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
try:
|
||||
response = session.post(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return True
|
||||
else:
|
||||
print(f"Ошибка при удалении клиента: {response.status_code} - {response.text}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Ошибка запроса: {e}")
|
||||
return False
|
||||
+24
-38
@@ -1,48 +1,46 @@
|
||||
import aiosqlite
|
||||
from datetime import datetime
|
||||
from config import DATABASE_PATH
|
||||
import aiosqlite
|
||||
|
||||
async def init_db():
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
await db.execute('''
|
||||
CREATE TABLE IF NOT EXISTS connections (
|
||||
tg_id INTEGER NOT NULL,
|
||||
client_id TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
expiry_time INTEGER NOT NULL,
|
||||
tg_id INTEGER PRIMARY KEY NOT NULL,
|
||||
balance REAL NOT NULL DEFAULT 0.0,
|
||||
PRIMARY KEY (tg_id, client_id)
|
||||
trial INTEGER NOT NULL DEFAULT 0
|
||||
)
|
||||
''')
|
||||
await db.execute('''
|
||||
CREATE TABLE IF NOT EXISTS keys (
|
||||
tg_id INTEGER NOT NULL, -- Добавлено поле tg_id
|
||||
tg_id INTEGER NOT NULL,
|
||||
client_id TEXT NOT NULL,
|
||||
email TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL,
|
||||
expiry_time INTEGER NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
PRIMARY KEY (tg_id, client_id) -- Изменено на (tg_id, client_id)
|
||||
PRIMARY KEY (tg_id, client_id)
|
||||
)
|
||||
''')
|
||||
await db.commit()
|
||||
|
||||
async def add_connection(tg_id: int, client_id: str, email: str, expiry_time: int, balance: float = 0.0):
|
||||
async def add_connection(tg_id: int, balance: float = 0.0, trial: int = 0):
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
await db.execute('''
|
||||
INSERT INTO connections (tg_id, client_id, email, expiry_time, balance)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (tg_id, client_id, email, expiry_time, balance))
|
||||
INSERT INTO connections (tg_id, balance, trial)
|
||||
VALUES (?, ?, ?)
|
||||
''', (tg_id, balance, trial))
|
||||
await db.commit()
|
||||
|
||||
async def store_key(tg_id: int, client_id: str, email: str, key: str):
|
||||
async def store_key(tg_id: int, client_id: str, email: str, expiry_time: int, key: str):
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
await db.execute('''
|
||||
INSERT INTO keys (tg_id, client_id, email, created_at, key)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (tg_id, client_id, email, int(datetime.utcnow().timestamp() * 1000), key))
|
||||
INSERT INTO keys (tg_id, client_id, email, created_at, expiry_time, key)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
''', (tg_id, client_id, email, int(datetime.utcnow().timestamp() * 1000), expiry_time, key))
|
||||
await db.commit()
|
||||
|
||||
|
||||
async def get_keys(tg_id: int):
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('''
|
||||
@@ -54,33 +52,15 @@ async def get_keys(tg_id: int):
|
||||
|
||||
async def has_active_key(tg_id: int) -> bool:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT COUNT(*) FROM connections WHERE tg_id = ? AND expiry_time > ?",
|
||||
(tg_id, int(datetime.utcnow().timestamp() * 1000))) as cursor:
|
||||
async with db.execute("SELECT COUNT(*) FROM keys WHERE tg_id = ?", (tg_id,)) as cursor:
|
||||
count = await cursor.fetchone()
|
||||
return count[0] > 0
|
||||
|
||||
async def get_active_key_email(tg_id: int) -> str:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT email FROM connections WHERE tg_id = ? AND expiry_time > ?",
|
||||
(tg_id, int(datetime.utcnow().timestamp() * 1000))) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
return record[0] if record else None
|
||||
|
||||
async def get_key_expiry_time(tg_id: int) -> datetime:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT expiry_time FROM connections WHERE tg_id = ? AND expiry_time > ?",
|
||||
(tg_id, int(datetime.utcnow().timestamp() * 1000))) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
if record:
|
||||
expiry_time = record[0]
|
||||
return datetime.utcfromtimestamp(expiry_time / 1000)
|
||||
return None
|
||||
|
||||
async def get_balance(tg_id: int) -> str:
|
||||
async def get_balance(tg_id: int) -> float:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT balance FROM connections WHERE tg_id = ?", (tg_id,)) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
return record[0] if record else "Неизвестно"
|
||||
return record[0] if record else 0.0
|
||||
|
||||
async def update_balance(tg_id: int, amount: float):
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
@@ -91,8 +71,14 @@ async def update_balance(tg_id: int, amount: float):
|
||||
''', (amount, tg_id))
|
||||
await db.commit()
|
||||
|
||||
async def get_trial(tg_id: int) -> int:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT trial FROM connections WHERE tg_id = ?", (tg_id,)) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
return record[0] if record else 0
|
||||
|
||||
async def get_key_count(tg_id: int) -> int:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('SELECT COUNT(*) FROM keys k JOIN connections c ON k.client_id = c.client_id WHERE c.tg_id = ?', (tg_id,)) as cursor:
|
||||
async with db.execute('SELECT COUNT(*) FROM keys WHERE tg_id = ?', (tg_id,)) as cursor:
|
||||
count = await cursor.fetchone()
|
||||
return count[0] if count else 0
|
||||
|
||||
Binary file not shown.
@@ -1,33 +0,0 @@
|
||||
from aiogram import types, Router
|
||||
from database import get_active_key_email
|
||||
from datetime import datetime
|
||||
import aiosqlite
|
||||
from config import DATABASE_PATH
|
||||
|
||||
router = Router()
|
||||
|
||||
@router.callback_query(lambda c: c.data == 'view_expiry')
|
||||
async def process_callback_view_expiry(callback_query: types.CallbackQuery):
|
||||
tg_id = callback_query.from_user.id
|
||||
|
||||
try:
|
||||
email = await get_active_key_email(tg_id)
|
||||
if email:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT expiry_time FROM connections WHERE tg_id = ? AND expiry_time > ?",
|
||||
(tg_id, int(datetime.utcnow().timestamp() * 1000))) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
if record:
|
||||
expiry_time = record[0]
|
||||
expiry_date = datetime.utcfromtimestamp(expiry_time / 1000).strftime("%Y-%m-%d %H:%M:%S")
|
||||
message_text = f"Дата окончания вашего ключа: {expiry_date}"
|
||||
else:
|
||||
message_text = "У вас нет активных ключей."
|
||||
else:
|
||||
message_text = "У вас нет активных ключей."
|
||||
|
||||
except Exception as e:
|
||||
message_text = f"Ошибка при получении даты окончания ключа: {e}"
|
||||
|
||||
await callback_query.message.reply(message_text)
|
||||
await callback_query.answer()
|
||||
+10
-9
@@ -2,7 +2,7 @@ from aiogram import types, Router
|
||||
import aiosqlite
|
||||
from bot import bot
|
||||
from datetime import datetime, timedelta
|
||||
from database import get_balance, update_balance
|
||||
from database import get_balance, update_balance, get_trial
|
||||
from client import extend_client_key, login_with_credentials
|
||||
from config import ADMIN_USERNAME, DATABASE_PATH, ADMIN_PASSWORD
|
||||
|
||||
@@ -16,7 +16,7 @@ async def process_callback_view_keys(callback_query: types.CallbackQuery):
|
||||
try:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('''
|
||||
SELECT email FROM connections WHERE tg_id = ?
|
||||
SELECT email FROM keys WHERE tg_id = ?
|
||||
''', (tg_id,)) as cursor:
|
||||
records = await cursor.fetchall()
|
||||
|
||||
@@ -49,6 +49,7 @@ async def process_callback_view_keys(callback_query: types.CallbackQuery):
|
||||
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
# Обработка запроса на просмотр информации о ключе
|
||||
@router.callback_query(lambda c: c.data.startswith('view_key_'))
|
||||
async def process_callback_view_key(callback_query: types.CallbackQuery):
|
||||
@@ -58,10 +59,10 @@ async def process_callback_view_key(callback_query: types.CallbackQuery):
|
||||
try:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('''
|
||||
SELECT k.key, c.expiry_time
|
||||
SELECT k.key, k.expiry_time
|
||||
FROM keys k
|
||||
JOIN connections c ON k.client_id = c.client_id
|
||||
WHERE c.tg_id = ? AND c.email = ?
|
||||
JOIN connections c ON k.tg_id = c.tg_id
|
||||
WHERE k.tg_id = ? AND k.email = ?
|
||||
''', (tg_id, key_name)) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
|
||||
@@ -105,7 +106,7 @@ async def process_callback_renew_key(callback_query: types.CallbackQuery):
|
||||
|
||||
try:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('SELECT client_id, email, expiry_time FROM connections WHERE tg_id = ?', (tg_id,)) as cursor:
|
||||
async with db.execute('SELECT client_id, email, expiry_time FROM keys WHERE tg_id = ?', (tg_id,)) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
|
||||
if record:
|
||||
@@ -145,7 +146,7 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery):
|
||||
|
||||
try:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('SELECT client_id, email, expiry_time FROM connections WHERE tg_id = ?', (tg_id,)) as cursor:
|
||||
async with db.execute('SELECT client_id, email, expiry_time FROM keys WHERE tg_id = ?', (tg_id,)) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
|
||||
if record:
|
||||
@@ -182,7 +183,7 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery):
|
||||
|
||||
if success:
|
||||
await update_balance(tg_id, -cost) # Списание средств с баланса
|
||||
await db.execute('UPDATE connections SET expiry_time = ? WHERE client_id = ?', (new_expiry_time, client_id))
|
||||
await db.execute('UPDATE keys SET expiry_time = ? WHERE client_id = ?', (new_expiry_time, client_id))
|
||||
await db.commit()
|
||||
response_message = f"Ваш ключ был успешно продлен на {days_to_extend // 30} месяц(-)."
|
||||
back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_keys')
|
||||
@@ -207,4 +208,4 @@ async def delete_previous_message(callback_query: types.CallbackQuery):
|
||||
# Обработка ошибок
|
||||
async def handle_error(tg_id, callback_query, message):
|
||||
await delete_previous_message(callback_query)
|
||||
await bot.send_message(tg_id, message)
|
||||
await bot.send_message(tg_id, message)
|
||||
@@ -1,45 +0,0 @@
|
||||
from aiogram import types, Router
|
||||
import re
|
||||
from database import get_active_key_email
|
||||
from auth import link, login_with_credentials
|
||||
from datetime import datetime
|
||||
import aiosqlite
|
||||
from config import DATABASE_PATH
|
||||
from config import ADMIN_USERNAME, ADMIN_PASSWORD
|
||||
|
||||
|
||||
router = Router()
|
||||
session = login_with_credentials(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||
|
||||
@router.callback_query(lambda c: c.data == 'view_stats')
|
||||
async def process_callback_view_stats(callback_query: types.CallbackQuery):
|
||||
tg_id = callback_query.from_user.id
|
||||
|
||||
try:
|
||||
email = await get_active_key_email(tg_id)
|
||||
if email:
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute("SELECT client_id FROM connections WHERE tg_id = ? AND expiry_time > ?",
|
||||
(tg_id, int(datetime.utcnow().timestamp() * 1000))) as cursor:
|
||||
record = await cursor.fetchone()
|
||||
if record:
|
||||
client_id = record[0]
|
||||
connection_link = link(session, client_id, email)
|
||||
|
||||
up_match = re.search(r'up=(\d+)', connection_link)
|
||||
down_match = re.search(r'down=(\d+)', connection_link)
|
||||
|
||||
up = up_match.group(1) if up_match else "Неизвестно"
|
||||
down = down_match.group(1) if down_match else "Неизвестно"
|
||||
|
||||
statistics = f"Статистика вашего ключа:\nЗагрузка: {up} MB\nВыгрузка: {down} MB"
|
||||
else:
|
||||
statistics = "У вас нет активных ключей."
|
||||
else:
|
||||
statistics = "У вас нет активных ключей."
|
||||
|
||||
except Exception as e:
|
||||
statistics = f"Ошибка при получении статистики: {e}"
|
||||
|
||||
await callback_query.message.reply(f"Ваша статистика:\n{statistics}")
|
||||
await callback_query.answer()
|
||||
+27
-80
@@ -10,13 +10,12 @@ from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
|
||||
from auth import login_with_credentials, link
|
||||
from client import add_client, extend_client_key
|
||||
from client import add_client
|
||||
from config import API_TOKEN, ADMIN_PASSWORD, ADMIN_USERNAME, ADMIN_CHAT_ID, DATABASE_PATH
|
||||
from database import add_connection, has_active_key, get_balance, store_key, update_balance
|
||||
from bot import dp
|
||||
from handlers.start import start_command
|
||||
from handlers.profile import process_callback_view_profile
|
||||
from handlers.keys import process_callback_view_keys
|
||||
from bot import bot
|
||||
|
||||
router = Router()
|
||||
@@ -27,7 +26,6 @@ def sanitize_key_name(key_name: str) -> str:
|
||||
|
||||
class Form(StatesGroup):
|
||||
waiting_for_key_name = State()
|
||||
waiting_for_expiry_date = State()
|
||||
viewing_profile = State()
|
||||
|
||||
# Обработка нажатия кнопки создания ключа
|
||||
@@ -41,10 +39,10 @@ async def process_callback_create_key(callback_query: CallbackQuery, state: FSMC
|
||||
"Хотите продолжить?",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='Да, создать новый ключ', callback_data='confirm_create_new_key')],
|
||||
[InlineKeyboardButton(text='Назад', callback_data='cancel_create_key')] # Изменили текст на "Назад"
|
||||
[InlineKeyboardButton(text='Назад', callback_data='cancel_create_key')]
|
||||
])
|
||||
)
|
||||
await state.update_data(creating_new_key=True) # Сохраняем состояние создания нового ключа
|
||||
await state.update_data(creating_new_key=True)
|
||||
else:
|
||||
await callback_query.message.edit_text("Вам будет выдан пробный ключ. Пожалуйста, выберите имя для вашего ключа:")
|
||||
await state.set_state(Form.waiting_for_key_name)
|
||||
@@ -53,31 +51,21 @@ async def process_callback_create_key(callback_query: CallbackQuery, state: FSMC
|
||||
|
||||
@dp.callback_query(F.data == 'cancel_create_key')
|
||||
async def cancel_create_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
await process_callback_view_profile(callback_query, state) # Возвращаем в профиль
|
||||
await process_callback_view_profile(callback_query, state)
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
|
||||
@dp.callback_query(F.data == 'confirm_create_new_key')
|
||||
async def confirm_create_new_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
await callback_query.message.edit_text("Пожалуйста, выберите имя для вашего нового ключа:")
|
||||
await state.set_state(Form.waiting_for_key_name)
|
||||
await state.update_data(creating_new_key=True) # Убедитесь, что это состояние сохранено
|
||||
await state.update_data(creating_new_key=True)
|
||||
await callback_query.answer()
|
||||
|
||||
@dp.callback_query(F.data == 'cancel_create_key')
|
||||
async def cancel_create_key(callback_query: CallbackQuery):
|
||||
await callback_query.message.edit_text("Создание нового ключа отменено.")
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
# Обработка текстовых сообщений
|
||||
@dp.message()
|
||||
async def handle_text(message: Message, state: FSMContext):
|
||||
current_state = await state.get_state()
|
||||
print(f"Received message: {message.text}, Current state: {current_state}")
|
||||
|
||||
# Обработка команд и переходов
|
||||
|
||||
if message.text == "Мой профиль":
|
||||
callback_query = types.CallbackQuery(
|
||||
id="1",
|
||||
@@ -93,7 +81,6 @@ async def handle_text(message: Message, state: FSMContext):
|
||||
await start_command(message)
|
||||
return
|
||||
|
||||
# Если ожидается имя ключа
|
||||
if current_state == Form.waiting_for_key_name.state:
|
||||
await handle_key_name_input(message, state)
|
||||
|
||||
@@ -106,7 +93,6 @@ async def handle_key_name_input(message: Message, state: FSMContext):
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
# Получаем данные состояния
|
||||
data = await state.get_data()
|
||||
creating_new_key = data.get('creating_new_key', False)
|
||||
|
||||
@@ -125,15 +111,23 @@ async def handle_key_name_input(message: Message, state: FSMContext):
|
||||
await state.clear()
|
||||
return
|
||||
|
||||
await update_balance(tg_id, -100) # Списание 100 рублей за новый ключ
|
||||
await update_balance(tg_id, -100)
|
||||
|
||||
try:
|
||||
# Создание клиента и получение ссылки
|
||||
add_client(session, client_id, email, tg_id, limit_ip=1, total_gb=0, expiry_time=expiry_time, enable=True, flow="xtls-rprx-vision")
|
||||
connection_link = link(session, client_id, email)
|
||||
|
||||
await add_connection(tg_id, client_id, email, expiry_time, 0)
|
||||
await store_key(tg_id, client_id, email, connection_link)
|
||||
# Проверка существующей записи
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
cursor = await db.execute('SELECT * FROM connections WHERE tg_id = ?', (tg_id,))
|
||||
existing_connection = await cursor.fetchone()
|
||||
|
||||
if existing_connection:
|
||||
await db.execute('UPDATE connections SET trial = 1 WHERE tg_id = ?', (tg_id,))
|
||||
else:
|
||||
await add_connection(tg_id, 0, 1)
|
||||
|
||||
await store_key(tg_id, client_id, email, expiry_time, connection_link)
|
||||
|
||||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='Инструкции по использованию', callback_data='instructions')],
|
||||
@@ -144,45 +138,9 @@ async def handle_key_name_input(message: Message, state: FSMContext):
|
||||
await message.reply(key_message, parse_mode="HTML", reply_markup=keyboard)
|
||||
except Exception as e:
|
||||
await message.reply(f"Ошибка при создании ключа: {e}")
|
||||
print(f"Ошибка при создании ключа: {e}")
|
||||
|
||||
await state.clear()
|
||||
|
||||
|
||||
# Обработка нажатия кнопки создания ключа
|
||||
@dp.callback_query(F.data == 'create_key')
|
||||
async def process_callback_create_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
tg_id = callback_query.from_user.id
|
||||
|
||||
if await has_active_key(tg_id):
|
||||
await callback_query.message.edit_text(
|
||||
"У вас уже есть активный ключ. Вы можете создать новый ключ за дополнительную плату в размере 100 рублей. "
|
||||
"Хотите продолжить?",
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='Да, создать новый ключ', callback_data='confirm_create_new_key')],
|
||||
[InlineKeyboardButton(text='Нет, оставить текущий', callback_data='cancel_create_key')]
|
||||
])
|
||||
)
|
||||
await state.update_data(creating_new_key=True) # Сохраняем состояние создания нового ключа
|
||||
else:
|
||||
await callback_query.message.edit_text("Вам будет выдан пробный ключ. Пожалуйста, выберите имя для вашего ключа:")
|
||||
await state.set_state(Form.waiting_for_key_name)
|
||||
|
||||
await callback_query.answer()
|
||||
|
||||
|
||||
@dp.callback_query(F.data == 'confirm_create_new_key')
|
||||
async def confirm_create_new_key(callback_query: CallbackQuery, state: FSMContext):
|
||||
await callback_query.message.edit_text("Пожалуйста, выберите имя для вашего нового ключа:")
|
||||
await state.set_state(Form.waiting_for_key_name)
|
||||
await callback_query.answer()
|
||||
|
||||
@dp.callback_query(F.data == 'cancel_create_key')
|
||||
async def cancel_create_key(callback_query: CallbackQuery):
|
||||
await callback_query.message.edit_text("Создание нового ключа отменено.")
|
||||
await callback_query.answer()
|
||||
|
||||
# Обработка кнопки "Инструкции"
|
||||
@dp.callback_query(F.data == 'instructions')
|
||||
async def handle_instructions(callback_query: CallbackQuery):
|
||||
instructions_message = (
|
||||
@@ -202,47 +160,36 @@ async def handle_instructions(callback_query: CallbackQuery):
|
||||
await callback_query.message.edit_text(instructions_message, parse_mode='Markdown', reply_markup=keyboard)
|
||||
await callback_query.answer()
|
||||
|
||||
# Обработка кнопки "Назад"
|
||||
@dp.callback_query(F.data == 'back_to_main')
|
||||
async def handle_back_to_main(callback_query: CallbackQuery):
|
||||
tg_id = callback_query.from_user.id
|
||||
new_callback_query = CallbackQuery(
|
||||
id=callback_query.id,
|
||||
from_user=callback_query.from_user,
|
||||
chat_instance=callback_query.chat_instance,
|
||||
data='view_keys',
|
||||
message=callback_query.message
|
||||
)
|
||||
|
||||
await process_callback_view_keys(new_callback_query)
|
||||
async def handle_back_to_main(callback_query: CallbackQuery, state: FSMContext):
|
||||
await process_callback_view_profile(callback_query, state)
|
||||
await callback_query.answer()
|
||||
|
||||
# Фоновая задача для продления ключей
|
||||
async def renew_expired_keys():
|
||||
while True:
|
||||
current_time = datetime.utcnow()
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
async with db.execute('SELECT tg_id, client_id FROM connections WHERE expiry_time <= ?', (int(current_time.timestamp() * 1000),)) as cursor:
|
||||
expired_keys = await cursor.fetchall()
|
||||
async with db.execute('SELECT tg_id FROM connections WHERE trial > 0') as cursor:
|
||||
active_keys = await cursor.fetchall()
|
||||
|
||||
for tg_id, client_id in expired_keys:
|
||||
for tg_id, in active_keys:
|
||||
balance = await get_balance(tg_id)
|
||||
if balance >= 100:
|
||||
new_expiry_time = int((current_time + timedelta(days=30)).timestamp() * 1000)
|
||||
|
||||
async with aiosqlite.connect(DATABASE_PATH) as db:
|
||||
await db.execute('UPDATE connections SET expiry_time = ? WHERE tg_id = ? AND client_id = ?', (new_expiry_time, tg_id, client_id))
|
||||
await db.execute('UPDATE keys SET expiry_time = ? WHERE tg_id = ?', (new_expiry_time, tg_id))
|
||||
await db.commit()
|
||||
|
||||
await update_balance(tg_id, -100)
|
||||
await extend_client_key(client_id)
|
||||
|
||||
print(f"Ключ для клиента {client_id} продлен на месяц и списано 100 рублей.")
|
||||
print(f"Ключ для пользователя {tg_id} продлен на месяц и списано 100 рублей.")
|
||||
else:
|
||||
print(f"Недостаточно средств на балансе для клиента {client_id}. Предложение пополнить баланс.")
|
||||
print(f"Недостаточно средств на балансе для пользователя {tg_id}. Предложение пополнить баланс.")
|
||||
replenish_keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(text='Пополнить баланс', callback_data='replenish_balance')]
|
||||
])
|
||||
await bot.send_message(tg_id, "Ваш баланс недостаточен для продления ключа. Пожалуйста, пополните баланс.", reply_markup=replenish_keyboard)
|
||||
|
||||
await asyncio.sleep(3600)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user