Refactor database and notification handlers for improved readability and consistency. Clean up import statements, enhance logging messages, and streamline function calls across multiple files. Ensure proper session handling in payment processing functions.
This commit is contained in:
+32
-26
@@ -3,7 +3,7 @@ from typing import Any
|
||||
|
||||
import asyncpg
|
||||
|
||||
from config import REFERRAL_BONUS_PERCENTAGES, DATABASE_URL
|
||||
from config import DATABASE_URL, REFERRAL_BONUS_PERCENTAGES
|
||||
from logger import logger
|
||||
|
||||
|
||||
@@ -611,9 +611,9 @@ async def get_all_users(conn):
|
||||
Exception: В случае ошибки при получении данных
|
||||
"""
|
||||
try:
|
||||
пользователи = await conn.fetch("SELECT tg_id FROM connections")
|
||||
logger.info(f"Получен список всех пользователей. Количество: {len(пользователи)}")
|
||||
return пользователи
|
||||
users = await conn.fetch("SELECT tg_id FROM connections")
|
||||
logger.info(f"Получен список всех пользователей. Количество: {len(users)}")
|
||||
return users
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при получении списка пользователей: {e}")
|
||||
raise
|
||||
@@ -679,10 +679,7 @@ async def handle_referral_on_balance_update(tg_id: int, amount: float):
|
||||
break
|
||||
|
||||
referrer_tg_id = referral['referrer_tg_id']
|
||||
referral_chain.append({
|
||||
'tg_id': referrer_tg_id,
|
||||
'level': level
|
||||
})
|
||||
referral_chain.append({'tg_id': referrer_tg_id, 'level': level})
|
||||
|
||||
# Переходим к следующему уровню
|
||||
current_tg_id = referrer_tg_id
|
||||
@@ -691,7 +688,7 @@ async def handle_referral_on_balance_update(tg_id: int, amount: float):
|
||||
for referral in referral_chain:
|
||||
referrer_tg_id = referral['tg_id']
|
||||
level = referral['level']
|
||||
|
||||
|
||||
# Расчет бонуса для текущего уровня
|
||||
bonus_percent = REFERRAL_BONUS_PERCENTAGES.get(level, 0)
|
||||
bonus = amount * bonus_percent
|
||||
@@ -699,7 +696,7 @@ async def handle_referral_on_balance_update(tg_id: int, amount: float):
|
||||
|
||||
if bonus > 0:
|
||||
logger.info(f"Начисление бонуса {bonus} рублей рефереру {referrer_tg_id} на уровне {level}")
|
||||
|
||||
|
||||
# Обновляем баланс реферера
|
||||
await update_balance(referrer_tg_id, bonus)
|
||||
|
||||
@@ -777,13 +774,11 @@ async def get_referral_stats(referrer_tg_id: int):
|
||||
""",
|
||||
referrer_tg_id,
|
||||
)
|
||||
|
||||
|
||||
# Преобразование результатов в словарь
|
||||
referrals_by_level = {
|
||||
record['level']: {
|
||||
'total': record['level_count'],
|
||||
'active': record['active_level_count']
|
||||
} for record in referrals_by_level_records
|
||||
record['level']: {'total': record['level_count'], 'active': record['active_level_count']}
|
||||
for record in referrals_by_level_records
|
||||
}
|
||||
logger.debug(f"Получена статистика рефералов по уровням: {referrals_by_level}")
|
||||
|
||||
@@ -1139,7 +1134,13 @@ async def check_notification_time(tg_id: int, notification_type: str, hours: int
|
||||
Exception: В случае ошибки при проверке времени уведомления
|
||||
"""
|
||||
try:
|
||||
result = await session.fetchrow(
|
||||
# Если сессия не передана, создаем новое подключение
|
||||
if session is None:
|
||||
conn = await asyncpg.connect(DATABASE_URL)
|
||||
else:
|
||||
conn = session
|
||||
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
SELECT
|
||||
CASE
|
||||
@@ -1149,23 +1150,28 @@ async def check_notification_time(tg_id: int, notification_type: str, hours: int
|
||||
END as can_notify
|
||||
FROM notifications
|
||||
WHERE tg_id = $2 AND notification_type = $3
|
||||
""",
|
||||
hours,
|
||||
tg_id,
|
||||
notification_type
|
||||
""",
|
||||
str(hours), # Преобразуем hours в строку
|
||||
tg_id,
|
||||
notification_type,
|
||||
)
|
||||
|
||||
# Если сессия не была передана, закрываем подключение
|
||||
if session is None and conn:
|
||||
await conn.close()
|
||||
|
||||
# Если записи нет, значит уведомление можно отправить
|
||||
if result is None:
|
||||
return True
|
||||
|
||||
can_notify = result['can_notify']
|
||||
|
||||
logger.info(f"Проверка уведомления типа {notification_type} для пользователя {tg_id}: {'можно отправить' if can_notify else 'слишком рано'}")
|
||||
|
||||
|
||||
logger.info(
|
||||
f"Проверка уведомления типа {notification_type} для пользователя {tg_id}: {'можно отправить' if can_notify else 'слишком рано'}"
|
||||
)
|
||||
|
||||
return can_notify
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при проверке времени уведомления для пользователя {tg_id}: {e}")
|
||||
raise
|
||||
|
||||
return True # По умолчанию разрешаем отправку уведомления
|
||||
|
||||
@@ -76,12 +76,12 @@ async def handle_delete_coupon(callback_query: types.CallbackQuery, session: Any
|
||||
result = await delete_coupon_from_db(coupon_code, session)
|
||||
|
||||
if result:
|
||||
await show_coupon_list(callback_query,session)
|
||||
await show_coupon_list(callback_query, session)
|
||||
else:
|
||||
await callback_query.message.answer(
|
||||
f"❌ Купон с кодом <b>{coupon_code}</b> не найден.",
|
||||
)
|
||||
await show_coupon_list(callback_query,session)
|
||||
await show_coupon_list(callback_query, session)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при удалении купона: {e}")
|
||||
|
||||
@@ -10,7 +10,15 @@ from aiogram.types import CallbackQuery, InlineKeyboardButton, Message
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
from config import CONNECT_ANDROID, CONNECT_IOS, DOWNLOAD_ANDROID, DOWNLOAD_IOS, PUBLIC_LINK, SUPPORT_CHAT_URL
|
||||
from database import add_connection, check_connection_exists, get_balance, get_trial, store_key, update_balance, use_trial
|
||||
from database import (
|
||||
add_connection,
|
||||
check_connection_exists,
|
||||
get_balance,
|
||||
get_trial,
|
||||
store_key,
|
||||
update_balance,
|
||||
use_trial,
|
||||
)
|
||||
from handlers.keys.key_utils import create_key_on_cluster
|
||||
from handlers.texts import KEY, KEY_TRIAL, NULL_BALANCE, RENEWAL_PLANS, key_message_success
|
||||
from handlers.utils import get_least_loaded_cluster, sanitize_key_name
|
||||
|
||||
+10
-10
@@ -8,7 +8,14 @@ from py3xui import AsyncApi
|
||||
|
||||
from client import delete_client
|
||||
from config import ADMIN_PASSWORD, ADMIN_USERNAME, CLUSTERS, DATABASE_URL, TOTAL_GB, TRIAL_TIME
|
||||
from database import delete_key, get_balance, update_balance, update_key_expiry,add_notification,check_notification_time
|
||||
from database import (
|
||||
add_notification,
|
||||
check_notification_time,
|
||||
delete_key,
|
||||
get_balance,
|
||||
update_balance,
|
||||
update_key_expiry,
|
||||
)
|
||||
from handlers.keys.key_utils import renew_key_in_cluster
|
||||
from handlers.texts import KEY_EXPIRY_10H, KEY_EXPIRY_24H, KEY_RENEWED, RENEWAL_PLANS
|
||||
from logger import logger
|
||||
@@ -220,10 +227,7 @@ async def notify_inactive_trial_users(bot: Bot, conn: asyncpg.Connection):
|
||||
try:
|
||||
# Проверяем, можно ли отправить уведомление
|
||||
can_notify = await check_notification_time(
|
||||
tg_id,
|
||||
'inactive_trial',
|
||||
hours=24, # Уведомление не чаще, чем раз в 24 часа
|
||||
session=conn
|
||||
tg_id, 'inactive_trial', hours=24, session=conn # Уведомление не чаще, чем раз в 24 часа
|
||||
)
|
||||
|
||||
if can_notify and not await is_bot_blocked(bot, tg_id):
|
||||
@@ -245,11 +249,7 @@ async def notify_inactive_trial_users(bot: Bot, conn: asyncpg.Connection):
|
||||
logger.info(f"Отправлено уведомление неактивному пользователю {tg_id}.")
|
||||
|
||||
# Добавляем запись о notification
|
||||
await add_notification(
|
||||
tg_id,
|
||||
'inactive_trial',
|
||||
session=conn
|
||||
)
|
||||
await add_notification(tg_id, 'inactive_trial', session=conn)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при отправке уведомления неактивному пользователю {tg_id}: {e}")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Any
|
||||
|
||||
from aiocryptopay import AioCryptoPay, Networks
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
@@ -26,7 +27,7 @@ class ReplenishBalanceState(StatesGroup):
|
||||
|
||||
|
||||
@router.callback_query(F.data == "pay_cryptobot")
|
||||
async def process_callback_pay_cryptobot(callback_query: types.CallbackQuery, state: FSMContext,session:Any):
|
||||
async def process_callback_pay_cryptobot(callback_query: types.CallbackQuery, state: FSMContext, session: Any):
|
||||
builder = InlineKeyboardBuilder()
|
||||
for i in range(0, len(PAYMENT_OPTIONS), 2):
|
||||
if i + 1 < len(PAYMENT_OPTIONS):
|
||||
@@ -58,7 +59,7 @@ async def process_callback_pay_cryptobot(callback_query: types.CallbackQuery, st
|
||||
if key_count == 0:
|
||||
exists = await check_connection_exists(callback_query.message.chat.id)
|
||||
if not exists:
|
||||
await add_connection(tg_id=callback_query.message.chat.id, balance=0.0, trial=0,session=session)
|
||||
await add_connection(tg_id=callback_query.message.chat.id, balance=0.0, trial=0, session=session)
|
||||
await callback_query.message.answer(
|
||||
"Выберите сумму пополнения:",
|
||||
reply_markup=builder.as_markup(),
|
||||
|
||||
@@ -49,7 +49,7 @@ def generate_payment_link(amount, inv_id, description, tg_id):
|
||||
|
||||
|
||||
@router.callback_query(F.data == "pay_robokassa")
|
||||
async def process_callback_pay_robokassa(callback_query: types.CallbackQuery, state: FSMContext,session:Any):
|
||||
async def process_callback_pay_robokassa(callback_query: types.CallbackQuery, state: FSMContext, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
logger.info(f"User {tg_id} initiated Robokassa payment.")
|
||||
|
||||
@@ -86,7 +86,7 @@ async def process_callback_pay_robokassa(callback_query: types.CallbackQuery, st
|
||||
if key_count == 0:
|
||||
exists = await check_connection_exists(tg_id)
|
||||
if not exists:
|
||||
await add_connection(tg_id, balance=0.0, trial=0,session=session)
|
||||
await add_connection(tg_id, balance=0.0, trial=0, session=session)
|
||||
logger.info(f"Created new connection for user {tg_id} with balance 0.0.")
|
||||
|
||||
await callback_query.message.answer(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Any
|
||||
|
||||
from aiogram import F, Router, types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
@@ -21,7 +22,7 @@ class ReplenishBalanceState(StatesGroup):
|
||||
|
||||
|
||||
@router.callback_query(F.data == "pay_stars")
|
||||
async def process_callback_pay_stars(callback_query: types.CallbackQuery, state: FSMContext,session:Any):
|
||||
async def process_callback_pay_stars(callback_query: types.CallbackQuery, state: FSMContext, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
@@ -59,7 +60,7 @@ async def process_callback_pay_stars(callback_query: types.CallbackQuery, state:
|
||||
if key_count == 0:
|
||||
exists = await check_connection_exists(tg_id)
|
||||
if not exists:
|
||||
await add_connection(tg_id, balance=0.0, trial=0,session=session)
|
||||
await add_connection(tg_id, balance=0.0, trial=0, session=session)
|
||||
|
||||
try:
|
||||
await callback_query.message.delete()
|
||||
|
||||
@@ -31,7 +31,7 @@ class ReplenishBalanceState(StatesGroup):
|
||||
|
||||
|
||||
@router.callback_query(F.data == "pay_yookassa")
|
||||
async def process_callback_pay_yookassa(callback_query: types.CallbackQuery, state: FSMContext,session:Any):
|
||||
async def process_callback_pay_yookassa(callback_query: types.CallbackQuery, state: FSMContext, session: Any):
|
||||
tg_id = callback_query.message.chat.id
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
@@ -68,7 +68,7 @@ async def process_callback_pay_yookassa(callback_query: types.CallbackQuery, sta
|
||||
if key_count == 0:
|
||||
exists = await check_connection_exists(tg_id)
|
||||
if not exists:
|
||||
await add_connection(tg_id, balance=0.0, trial=0,session=session)
|
||||
await add_connection(tg_id, balance=0.0, trial=0, session=session)
|
||||
|
||||
await callback_query.message.answer(
|
||||
text="Выберите сумму пополнения:",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from typing import Any, Awaitable, Callable, Dict
|
||||
from logger import logger
|
||||
|
||||
from aiogram import BaseMiddleware
|
||||
from aiogram.types import CallbackQuery, Message, TelegramObject
|
||||
|
||||
|
||||
class DeleteMessageMiddleware(BaseMiddleware):
|
||||
async def __call__(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user