SuperNode/SyncTimeout/pytz

This commit is contained in:
Vladless
2025-01-14 12:16:14 +03:00
parent 0391bd90e9
commit 722a0f4913
12 changed files with 1730 additions and 1630 deletions
+10 -4
View File
@@ -1,6 +1,6 @@
import py3xui
from config import LIMIT_IP
from config import LIMIT_IP, SUPERNODE
from logger import logger
@@ -15,6 +15,7 @@ async def add_client(
enable: bool,
flow: str,
inbound_id: int,
sub_id
):
"""
Adds a client to the server via 3x-ui.
@@ -30,7 +31,7 @@ async def add_client(
expiry_time=expiry_time,
enable=enable,
tg_id=tg_id,
sub_id=email,
sub_id=sub_id,
flow=flow,
)
@@ -54,7 +55,7 @@ async def add_client(
async def extend_client_key(
xui, inbound_id, email: str, new_expiry_time: int, client_id: str, total_gb: int
xui, inbound_id, email: str, new_expiry_time: int, client_id: str, total_gb: int, sub_id = str
):
"""
Функция для обновления срока действия ключа клиента по email.
@@ -78,7 +79,7 @@ async def extend_client_key(
client.id = client_id
client.expiry_time = new_expiry_time
client.flow = "xtls-rprx-vision"
client.sub_id = email
client.sub_id = sub_id
client.total_gb = total_gb
client.enable = True
client.limit_ip = LIMIT_IP
@@ -106,6 +107,11 @@ async def delete_client(
"""
await xui.login()
try:
if SUPERNODE:
await xui.client.delete(inbound_id, client_id)
logger.info(f"Клиент с ID {client_id} был удален успешно (SUPERNODE).")
return True
client = await xui.client.get_by_email(email)
if not client:
+18 -12
View File
@@ -9,7 +9,7 @@ from aiogram.utils.keyboard import InlineKeyboardBuilder
from py3xui import AsyncApi
from backup import create_backup_and_send_to_admins
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL
from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SUPERNODE
from database import check_unique_server_name, get_servers_from_db
from filters.admin import IsAdminFilter
from handlers.keys.key_utils import create_key_on_cluster
@@ -378,18 +378,24 @@ async def sync_cluster_handler(callback_query: types.CallbackQuery):
)
return
servers = await get_servers_from_db()
cluster_servers = servers.get(cluster_name, [])
for key in keys_to_sync:
try:
await create_key_on_cluster(
cluster_name,
key["tg_id"],
key["client_id"],
key["email"],
key["expiry_time"],
)
await asyncio.sleep(0.2)
except Exception as e:
logger.error(f"Ошибка при добавлении ключа {key['client_id']} в кластер {cluster_name}: {e}")
for server_info in cluster_servers:
server_name = server_info.get("server_name", "unknown")
email = f"{key['email']}_{server_name.lower()}" if SUPERNODE else key['email']
try:
await create_key_on_cluster(
cluster_name,
key["tg_id"],
key["client_id"],
email,
key["expiry_time"],
)
await asyncio.sleep(0.6)
except Exception as e:
logger.error(f"Ошибка при добавлении ключа {key['client_id']} в кластер {cluster_name}: {e}")
await callback_query.message.answer(
f"✅ Ключи успешно синхронизированы для кластера {cluster_name}.",
+3 -1
View File
@@ -2,6 +2,7 @@ import asyncio
from datetime import datetime
from typing import Any
import pytz
from aiogram import Bot, F, Router, types
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
@@ -496,8 +497,9 @@ async def handle_expiry_time_input(
try:
expiry_time_str = message.text
moscow_tz = pytz.timezone("Europe/Moscow")
expiry_time = int(
datetime.strptime(expiry_time_str, "%Y-%m-%d %H:%M:%S").timestamp() * 1000
datetime.strptime(expiry_time_str, "%Y-%m-%d %H:%M:%S").replace(tzinfo=moscow_tz).timestamp() * 1000
)
client_id = await get_client_id_by_email(email)
+5
View File
@@ -1,3 +1,8 @@
PAY = "Пополнить"
PAY_2 = "Оплатить"
BACK = "⬅️ Назад"
CUSTOM_SUM = "💰 Ввести свою сумму"
PROFILE = "👤 Личный кабинет"
KEY_CREATION_PAYMENT_MESSAGE = "Вы выбрали пополнение на {amount} рублей для создания нового ключа. Перейдите по ссылке для оплаты:"
KEY_RENEWAL_PAYMENT_MESSAGE = "Вы выбрали пополнение на {amount} рублей для продления ключа. Перейдите по ссылке для оплаты:"
DEFAULT_PAYMENT_MESSAGE = "Вы выбрали пополнение на {amount} рублей. Перейдите по ссылке для оплаты:"
+13 -21
View File
@@ -3,6 +3,7 @@ import uuid
from datetime import datetime, timedelta
from typing import Any
import pytz
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
@@ -178,6 +179,9 @@ async def create_key(
message_or_query: Message | CallbackQuery | None = None,
):
"""Создаёт ключ с заданным сроком действия."""
moscow_tz = pytz.timezone("Europe/Moscow")
expiry_time = expiry_time.astimezone(moscow_tz)
while True:
key_name = generate_random_email()
logger.info(f"Generated random key name for user {tg_id}: {key_name}")
@@ -195,7 +199,7 @@ async def create_key(
client_id = str(uuid.uuid4())
email = key_name.lower()
expiry_timestamp = int(expiry_time.timestamp() * 1000)
expiry_timestamp = int(expiry_time.astimezone(moscow_tz).timestamp() * 1000)
public_link = f"{PUBLIC_LINK}{email}/{tg_id}"
try:
@@ -229,19 +233,13 @@ async def create_key(
except Exception as e:
logger.error(f"Error while creating the key for user {tg_id} on cluster: {e}")
error_message = "❌ Произошла ошибка при создании подписки. Пожалуйста, попробуйте снова."
if isinstance(message_or_query, Message):
await message_or_query.answer(
"❌ Произошла ошибка при создании ключа. Пожалуйста, попробуйте снова."
)
await message_or_query.answer(error_message)
elif isinstance(message_or_query, CallbackQuery):
await message_or_query.message.answer(
"❌ Произошла ошибка при создании ключа. Пожалуйста, попробуйте снова."
)
await message_or_query.message.answer(error_message)
else:
await bot.send_message(
chat_id=tg_id,
text="❌ Произошла ошибка при создании ключа. Пожалуйста, попробуйте снова.",
)
await bot.send_message(chat_id=tg_id, text=error_message)
return
builder = InlineKeyboardBuilder()
@@ -252,9 +250,7 @@ async def create_key(
)
builder.row(
InlineKeyboardButton(text=IMPORT_IOS, url=f"{CONNECT_IOS}{public_link}"),
InlineKeyboardButton(
text=IMPORT_ANDROID, url=f"{CONNECT_ANDROID}{public_link}"
),
InlineKeyboardButton(text=IMPORT_ANDROID, url=f"{CONNECT_ANDROID}{public_link}"),
)
builder.row(
InlineKeyboardButton(text=PC_BUTTON, callback_data=f"connect_pc|{email}"),
@@ -262,20 +258,16 @@ async def create_key(
)
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
remaining_time = expiry_time - datetime.utcnow()
remaining_time = expiry_time - datetime.now(moscow_tz)
days = remaining_time.days
key_message = key_message_success(public_link, f"⏳ Осталось дней: {days} 📅")
if isinstance(message_or_query, Message):
await message_or_query.answer(key_message, reply_markup=builder.as_markup())
elif isinstance(message_or_query, CallbackQuery):
await message_or_query.message.answer(
key_message, reply_markup=builder.as_markup()
)
await message_or_query.message.answer(key_message, reply_markup=builder.as_markup())
else:
await bot.send_message(
chat_id=tg_id, text=key_message, reply_markup=builder.as_markup()
)
await bot.send_message(chat_id=tg_id, text=key_message, reply_markup=builder.as_markup())
if state:
await state.clear()
+30 -13
View File
@@ -3,21 +3,14 @@ import asyncio
from py3xui import AsyncApi
from client import add_client, delete_client, extend_client_key
from config import ADMIN_PASSWORD, ADMIN_USERNAME, LIMIT_IP, TOTAL_GB
from config import ADMIN_PASSWORD, ADMIN_USERNAME, LIMIT_IP, SUPERNODE, TOTAL_GB
from database import get_servers_from_db
from logger import logger
async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_timestamp):
"""
Создает ключ на всех серверах указанного кластера.
:param cluster_id: ID кластера.
:param tg_id: Telegram ID пользователя.
:param client_id: Уникальный идентификатор клиента.
:param email: Email клиента.
:param expiry_timestamp: Время истечения ключа (timestamp в миллисекундах).
:param allow_existing: Игнорируется, ключи всегда продолжают выполнение.
Создает ключ на всех серверах указанного кластера с одинаковым sub_id и уникальным email при активном SUPERNODE.
"""
try:
tasks = []
@@ -35,17 +28,26 @@ async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_time
)
inbound_id = server_info.get("inbound_id")
server_name = server_info.get("server_name", "unknown")
if not inbound_id:
logger.warning(
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
f"INBOUND_ID отсутствует для сервера {server_name}. Пропуск."
)
continue
if SUPERNODE:
unique_email = f"{email}_{server_name.lower()}"
sub_id = email
else:
unique_email = email
sub_id = unique_email
tasks.append(
add_client(
xui,
client_id,
email,
unique_email,
tg_id,
limit_ip=LIMIT_IP,
total_gb=TOTAL_GB,
@@ -53,9 +55,13 @@ async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_time
enable=True,
flow="xtls-rprx-vision",
inbound_id=int(inbound_id),
sub_id=sub_id
)
)
if SUPERNODE:
await asyncio.sleep(0.2)
await asyncio.gather(*tasks)
except Exception as e:
@@ -63,6 +69,7 @@ async def create_key_on_cluster(cluster_id, tg_id, client_id, email, expiry_time
raise e
async def renew_key_in_cluster(cluster_id, email, client_id, new_expiry_time, total_gb):
try:
servers = await get_servers_from_db()
@@ -80,20 +87,30 @@ async def renew_key_in_cluster(cluster_id, email, client_id, new_expiry_time, to
)
inbound_id = server_info.get("inbound_id")
server_name = server_info.get("server_name", "unknown")
if not inbound_id:
logger.warning(
f"INBOUND_ID отсутствует для сервера {server_info.get('server_name', 'unknown')}. Пропуск."
f"INBOUND_ID отсутствует для сервера {server_name}. Пропуск."
)
continue
if SUPERNODE:
unique_email = f"{email}_{server_name.lower()}"
sub_id = email
else:
unique_email = email
sub_id = unique_email
tasks.append(
extend_client_key(
xui,
int(inbound_id),
email,
unique_email,
new_expiry_time,
client_id,
total_gb,
sub_id
)
)
+6 -1
View File
@@ -6,7 +6,7 @@ import aiohttp
import asyncpg
from aiohttp import web
from config import DATABASE_URL, PROJECT_NAME, SUB_MESSAGE, TRANSITION_DATE_STR
from config import DATABASE_URL, PROJECT_NAME, SUB_MESSAGE, SUPERNODE, TRANSITION_DATE_STR
from database import get_servers_from_db
from logger import logger
@@ -35,6 +35,11 @@ async def fetch_url_content(url, tg_id):
async def combine_unique_lines(urls, tg_id, query_string):
if SUPERNODE:
logger.info(f"Режим SUPERNODE активен. Возвращаем первую ссылку для tg_id: {tg_id}")
urls_with_query = [f"{urls[0]}?{query_string}"] if urls else []
return await fetch_url_content(urls_with_query[0], tg_id) if urls_with_query else []
all_lines = []
logger.info(
f"Начинаем объединение подписок для tg_id: {tg_id}, запрос: {query_string}"
+12 -17
View File
@@ -7,14 +7,7 @@ import pytz
from py3xui import AsyncApi
from client import add_client
from config import (
ADMIN_PASSWORD,
ADMIN_USERNAME,
LIMIT_IP,
PUBLIC_LINK,
TOTAL_GB,
TRIAL_TIME,
)
from config import ADMIN_PASSWORD, ADMIN_USERNAME, LIMIT_IP, PUBLIC_LINK, SUPERNODE, TOTAL_GB, TRIAL_TIME
from database import get_servers_from_db, store_key, use_trial
from handlers.texts import INSTRUCTIONS
from handlers.utils import generate_random_email, get_least_loaded_cluster
@@ -26,18 +19,16 @@ async def create_trial_key(tg_id: int, session: Any):
trial_status = await session.fetchval(
"SELECT trial FROM connections WHERE tg_id = $1", tg_id
)
if trial_status == 1:
return {"error": "Вы уже использовали пробную версию."}
except Exception as e:
logger.error(f"Ошибка при проверке триала: {e}")
client_id = str(uuid.uuid4())
email = generate_random_email()
public_link = f"{PUBLIC_LINK}{email}/{tg_id}"
base_email = generate_random_email()
public_link = f"{PUBLIC_LINK}{base_email}/{tg_id}"
instructions = INSTRUCTIONS
result = {"key": public_link, "instructions": instructions, "email": email}
result = {"key": public_link, "instructions": instructions, "email": base_email}
moscow_tz = pytz.timezone("Europe/Moscow")
current_time = datetime.now(moscow_tz)
@@ -46,14 +37,18 @@ async def create_trial_key(tg_id: int, session: Any):
clusters = await get_servers_from_db()
least_loaded_cluster = await get_least_loaded_cluster()
if least_loaded_cluster not in clusters:
raise ValueError(f"Кластер {least_loaded_cluster} не найден в базе данных.")
servers_in_cluster = clusters[least_loaded_cluster]
tasks = []
for server_info in servers_in_cluster:
for index, server_info in enumerate(servers_in_cluster):
if SUPERNODE:
email = f"{base_email}{index}"
else:
email = base_email
tasks.append(
add_client(
AsyncApi(
@@ -70,6 +65,7 @@ async def create_trial_key(tg_id: int, session: Any):
enable=True,
flow="xtls-rprx-vision",
inbound_id=int(server_info["inbound_id"]),
sub_id=base_email
)
)
@@ -78,7 +74,7 @@ async def create_trial_key(tg_id: int, session: Any):
await store_key(
tg_id,
client_id,
email,
base_email,
expiry_timestamp,
public_link,
server_id=least_loaded_cluster,
@@ -86,5 +82,4 @@ async def create_trial_key(tg_id: int, session: Any):
)
await use_trial(tg_id, session)
return result
+27 -27
View File
@@ -3667,7 +3667,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
* new_expiry_time = data.get("new_expiry_time")
* total_gb = data.get("total_gb") # <<<<<<<<<<<<<<
* cost = data.get("cost")
* email = data.get("email") # email
* email = data.get("email")
*/
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 37, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_5);
@@ -3701,7 +3701,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
* new_expiry_time = data.get("new_expiry_time")
* total_gb = data.get("total_gb")
* cost = data.get("cost") # <<<<<<<<<<<<<<
* email = data.get("email") # email
* email = data.get("email")
*
*/
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_data, __pyx_n_s_get); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 38, __pyx_L13_error)
@@ -3735,7 +3735,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
/* "handlers/payments/utils.py":39
* total_gb = data.get("total_gb")
* cost = data.get("cost")
* email = data.get("email") # email # <<<<<<<<<<<<<<
* email = data.get("email") # <<<<<<<<<<<<<<
*
* if not all([plan, client_id, new_expiry_time, email]):
*/
@@ -3768,7 +3768,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__pyx_t_9 = 0;
/* "handlers/payments/utils.py":41
* email = data.get("email") # email
* email = data.get("email")
*
* if not all([plan, client_id, new_expiry_time, email]): # <<<<<<<<<<<<<<
* logger.error(f"[RENEW] {user_id}")
@@ -3850,7 +3850,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
goto __pyx_L12_return;
/* "handlers/payments/utils.py":41
* email = data.get("email") # email
* email = data.get("email")
*
* if not all([plan, client_id, new_expiry_time, email]): # <<<<<<<<<<<<<<
* logger.error(f"[RENEW] {user_id}")
@@ -4625,8 +4625,8 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
* return
*
* builder.row( # <<<<<<<<<<<<<<
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"),
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
*/
__pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_builder, __pyx_n_s_row); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 73, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_9);
@@ -4634,19 +4634,19 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
/* "handlers/payments/utils.py":74
*
* builder.row(
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"), # <<<<<<<<<<<<<<
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"),
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"), # <<<<<<<<<<<<<<
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
* )
*/
__Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_InlineKeyboardButton); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_8);
__pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_RENEW_KEY); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_ADD_KEY); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_6);
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_text, __pyx_t_6) < 0) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_callback_data, __pyx_n_u_view_keys) < 0) __PYX_ERR(0, 74, __pyx_L13_error)
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_callback_data, __pyx_n_u_create_key) < 0) __PYX_ERR(0, 74, __pyx_L13_error)
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_empty_tuple, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 74, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
@@ -4654,8 +4654,8 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
/* "handlers/payments/utils.py":75
* builder.row(
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"), # <<<<<<<<<<<<<<
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"),
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"), # <<<<<<<<<<<<<<
* )
* await bot.send_message(
*/
@@ -4663,11 +4663,11 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_8 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 75, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_8);
__Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_ADD_KEY); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 75, __pyx_L13_error)
__Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_RENEW_KEY); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 75, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_12);
if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_text, __pyx_t_12) < 0) __PYX_ERR(0, 75, __pyx_L13_error)
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_callback_data, __pyx_n_u_create_key) < 0) __PYX_ERR(0, 75, __pyx_L13_error)
if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_callback_data, __pyx_n_u_view_keys) < 0) __PYX_ERR(0, 75, __pyx_L13_error)
__pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_8); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 75, __pyx_L13_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
@@ -4699,7 +4699,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
/* "handlers/payments/utils.py":77
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"),
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
* )
* await bot.send_message( # <<<<<<<<<<<<<<
* chat_id=user_id,
@@ -4782,7 +4782,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
/* "handlers/payments/utils.py":77
* InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"),
* InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"),
* )
* await bot.send_message( # <<<<<<<<<<<<<<
* chat_id=user_id,
@@ -4899,7 +4899,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
* finally:
* await conn.close() # <<<<<<<<<<<<<<
* else:
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"))
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"))
*/
/*finally:*/ {
/*normal exit:*/{
@@ -5241,8 +5241,8 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
/* "handlers/payments/utils.py":87
* await conn.close()
* else:
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys")) # <<<<<<<<<<<<<<
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"))
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key")) # <<<<<<<<<<<<<<
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"))
*
*/
/*else*/ {
@@ -5252,11 +5252,11 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_GOTREF(__pyx_t_9);
__pyx_t_12 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 87, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_RENEW_KEY); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 87, __pyx_L4_error)
__Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_ADD_KEY); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 87, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_6);
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_text, __pyx_t_6) < 0) __PYX_ERR(0, 87, __pyx_L4_error)
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_callback_data, __pyx_n_u_view_keys) < 0) __PYX_ERR(0, 87, __pyx_L4_error)
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_callback_data, __pyx_n_u_create_key) < 0) __PYX_ERR(0, 87, __pyx_L4_error)
__pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_empty_tuple, __pyx_t_12); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 87, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
@@ -5288,8 +5288,8 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
/* "handlers/payments/utils.py":88
* else:
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"))
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key")) # <<<<<<<<<<<<<<
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"))
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys")) # <<<<<<<<<<<<<<
*
* await bot.send_message(
*/
@@ -5299,11 +5299,11 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_12 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 88, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_ADD_KEY); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 88, __pyx_L4_error)
__Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_RENEW_KEY); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 88, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_9);
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_text, __pyx_t_9) < 0) __PYX_ERR(0, 88, __pyx_L4_error)
__Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_callback_data, __pyx_n_u_create_key) < 0) __PYX_ERR(0, 88, __pyx_L4_error)
if (PyDict_SetItem(__pyx_t_12, __pyx_n_s_callback_data, __pyx_n_u_view_keys) < 0) __PYX_ERR(0, 88, __pyx_L4_error)
__pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_12); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 88, __pyx_L4_error)
__Pyx_GOTREF(__pyx_t_9);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
@@ -5334,7 +5334,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
/* "handlers/payments/utils.py":90
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"))
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"))
*
* await bot.send_message( # <<<<<<<<<<<<<<
* chat_id=user_id,
@@ -5417,7 +5417,7 @@ static PyObject *__pyx_gb_8handlers_8payments_5utils_2generator(__pyx_CoroutineO
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
/* "handlers/payments/utils.py":90
* builder.row(InlineKeyboardButton(text=ADD_KEY, callback_data="create_key"))
* builder.row(InlineKeyboardButton(text=RENEW_KEY, callback_data="view_keys"))
*
* await bot.send_message( # <<<<<<<<<<<<<<
* chat_id=user_id,
File diff suppressed because it is too large Load Diff