fix: admin balance buttons / show tariff in key / show tariff on buy/renew / backup send modes
This commit is contained in:
@@ -5,9 +5,13 @@ from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from aiogram.types import BufferedInputFile
|
||||
from aiogram import Bot
|
||||
|
||||
from bot import bot
|
||||
from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER, PG_HOST, PG_PORT
|
||||
from config import (
|
||||
ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER, PG_HOST, PG_PORT,
|
||||
BACKUP_SEND_MODE, BACKUP_CHANNEL_ID, BACKUP_CHANNEL_THREAD_ID, BACKUP_OTHER_BOT_TOKEN, BACKUP_CAPTION
|
||||
)
|
||||
from logger import logger
|
||||
|
||||
|
||||
@@ -139,20 +143,67 @@ async def _send_backup_to_admins(backup_file_path: str) -> None:
|
||||
if not backup_file_path or not os.path.exists(backup_file_path):
|
||||
raise FileNotFoundError(f"Файл бэкапа не найден: {backup_file_path}")
|
||||
|
||||
async def send_default():
|
||||
for admin_id in ADMIN_ID:
|
||||
try:
|
||||
await bot.send_document(
|
||||
chat_id=admin_id, document=backup_input_file
|
||||
)
|
||||
logger.info(f"Бэкап базы данных отправлен админу: {admin_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Не удалось отправить бэкап админу {admin_id}: {e}")
|
||||
|
||||
try:
|
||||
async with aiofiles.open(backup_file_path, "rb") as backup_file:
|
||||
backup_data = await backup_file.read()
|
||||
filename = os.path.basename(backup_file_path)
|
||||
backup_input_file = BufferedInputFile(file=backup_data, filename=filename)
|
||||
|
||||
for admin_id in ADMIN_ID:
|
||||
if BACKUP_SEND_MODE == "default":
|
||||
await send_default()
|
||||
|
||||
elif BACKUP_SEND_MODE == "channel":
|
||||
channel_id = BACKUP_CHANNEL_ID.strip()
|
||||
thread_id = BACKUP_CHANNEL_THREAD_ID.strip()
|
||||
if not channel_id:
|
||||
logger.error("BACKUP_CHANNEL_ID не задан для режима 'channel', fallback на default")
|
||||
await send_default()
|
||||
return
|
||||
send_kwargs = dict(chat_id=channel_id, document=backup_input_file)
|
||||
if thread_id:
|
||||
send_kwargs["message_thread_id"] = int(thread_id)
|
||||
if BACKUP_CAPTION:
|
||||
send_kwargs["caption"] = BACKUP_CAPTION
|
||||
try:
|
||||
await bot.send_document(
|
||||
chat_id=admin_id, document=backup_input_file
|
||||
)
|
||||
logger.info(f"Бэкап базы данных отправлен админу: {admin_id}")
|
||||
await bot.send_document(**send_kwargs)
|
||||
logger.info(f"Бэкап базы данных отправлен в канал: {channel_id} (топик: {thread_id})")
|
||||
except Exception as e:
|
||||
logger.error(f"Не удалось отправить бэкап админу {admin_id}: {e}")
|
||||
logger.error(f"Не удалось отправить бэкап в канал {channel_id}: {e}, fallback на default")
|
||||
await send_default()
|
||||
|
||||
elif BACKUP_SEND_MODE == "bot":
|
||||
if not BACKUP_OTHER_BOT_TOKEN:
|
||||
logger.error("BACKUP_OTHER_BOT_TOKEN не задан для режима 'bot', fallback на default")
|
||||
await send_default()
|
||||
return
|
||||
other_bot = Bot(token=BACKUP_OTHER_BOT_TOKEN)
|
||||
try:
|
||||
for admin_id in ADMIN_ID:
|
||||
try:
|
||||
send_kwargs = dict(chat_id=admin_id, document=backup_input_file)
|
||||
if BACKUP_CAPTION:
|
||||
send_kwargs["caption"] = BACKUP_CAPTION
|
||||
await other_bot.send_document(**send_kwargs)
|
||||
logger.info(f"Бэкап базы данных отправлен админу через другого бота: {admin_id}")
|
||||
except Exception as e:
|
||||
logger.error(f"Не удалось отправить бэкап админу {admin_id} через другого бота: {e}")
|
||||
await other_bot.session.close()
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при отправке через другого бота: {e}, fallback на default")
|
||||
await send_default()
|
||||
else:
|
||||
logger.error(f"Неизвестный BACKUP_SEND_MODE: {BACKUP_SEND_MODE}, fallback на default")
|
||||
await send_default()
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при отправке бэкапа в Telegram: {e}")
|
||||
logger.error(f"Ошибка при отправке бэкапа: {e}")
|
||||
raise
|
||||
|
||||
@@ -99,7 +99,7 @@ def build_user_edit_kb(
|
||||
def build_users_balance_change_kb(tg_id: int) -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(
|
||||
text=BACK, # todo: fix magic text was set
|
||||
text=BACK,
|
||||
callback_data=AdminUserEditorCallback(
|
||||
action="users_balance_edit", tg_id=tg_id
|
||||
).pack(),
|
||||
@@ -112,30 +112,18 @@ async def build_users_balance_kb(
|
||||
) -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
|
||||
result = await session.execute(select(Tariff))
|
||||
tariffs = result.scalars().all()
|
||||
|
||||
unique_prices = set()
|
||||
for tariff in tariffs:
|
||||
months = tariff.duration_days // 30
|
||||
if months < 1:
|
||||
continue
|
||||
price = tariff.price_rub
|
||||
if price in unique_prices:
|
||||
continue
|
||||
unique_prices.add(price)
|
||||
|
||||
for amount in [100, 250, 500, 1000]:
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"+ {price}₽ ({months} мес.)",
|
||||
text=f"+ {amount}₽",
|
||||
callback_data=AdminUserEditorCallback(
|
||||
action="users_balance_add", tg_id=tg_id, data=price
|
||||
action="users_balance_add", tg_id=tg_id, data=amount
|
||||
).pack(),
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text=f"- {price}₽ ({months} мес.)",
|
||||
text=f"- {amount}₽",
|
||||
callback_data=AdminUserEditorCallback(
|
||||
action="users_balance_add", tg_id=tg_id, data=-price
|
||||
action="users_balance_add", tg_id=tg_id, data=-amount
|
||||
).pack(),
|
||||
),
|
||||
)
|
||||
@@ -172,7 +160,7 @@ async def build_users_balance_kb(
|
||||
def build_users_key_show_kb(tg_id: int, email: str) -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(
|
||||
text=BACK, # todo: fix magic text was set
|
||||
text=BACK,
|
||||
callback_data=AdminUserEditorCallback(
|
||||
action="users_key_edit", tg_id=tg_id, data=email, edit=True
|
||||
).pack(),
|
||||
@@ -187,52 +175,39 @@ async def build_users_key_expiry_kb(
|
||||
|
||||
result = await session.execute(select(Key.server_id, Key.tariff_id).where(Key.email == email))
|
||||
row = result.first()
|
||||
if not row or not row[0] or not row[1]:
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text="⚠️ Сервер не найден",
|
||||
callback_data=AdminUserEditorCallback(
|
||||
action="users_key_edit", tg_id=tg_id, data=email
|
||||
).pack(),
|
||||
server_id, tariff_id = (row if row else (None, None))
|
||||
|
||||
if tariff_id:
|
||||
result = await session.execute(select(Tariff.group_code).where(Tariff.id == tariff_id))
|
||||
row = result.first()
|
||||
if row and row[0]:
|
||||
group_code = row[0]
|
||||
result = await session.execute(
|
||||
select(Tariff)
|
||||
.where(Tariff.group_code == group_code, Tariff.is_active.is_(True))
|
||||
)
|
||||
)
|
||||
return builder.as_markup()
|
||||
|
||||
server_id, tariff_id = row
|
||||
|
||||
result = await session.execute(select(Tariff.group_code).where(Tariff.id == tariff_id))
|
||||
row = result.first()
|
||||
if not row or not row[0]:
|
||||
return builder.as_markup()
|
||||
group_code = row[0]
|
||||
|
||||
result = await session.execute(
|
||||
select(Tariff)
|
||||
.where(Tariff.group_code == group_code, Tariff.is_active.is_(True))
|
||||
)
|
||||
tariffs = result.scalars().all()
|
||||
|
||||
unique_durations = set()
|
||||
for tariff in tariffs:
|
||||
days = tariff.duration_days
|
||||
if days < 1 or days in unique_durations:
|
||||
continue
|
||||
unique_durations.add(days)
|
||||
label = format_days(days)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"+ {label}",
|
||||
callback_data=AdminUserKeyEditorCallback(
|
||||
action="add", tg_id=tg_id, data=email, month=days
|
||||
).pack(),
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text=f"- {label}",
|
||||
callback_data=AdminUserKeyEditorCallback(
|
||||
action="add", tg_id=tg_id, data=email, month=-days
|
||||
).pack(),
|
||||
),
|
||||
)
|
||||
tariffs = result.scalars().all()
|
||||
unique_durations = set()
|
||||
for tariff in tariffs:
|
||||
days = tariff.duration_days
|
||||
if days < 1 or days in unique_durations:
|
||||
continue
|
||||
unique_durations.add(days)
|
||||
label = format_days(days)
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"+ {label}",
|
||||
callback_data=AdminUserKeyEditorCallback(
|
||||
action="add", tg_id=tg_id, data=email, month=days
|
||||
).pack(),
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text=f"- {label}",
|
||||
callback_data=AdminUserKeyEditorCallback(
|
||||
action="add", tg_id=tg_id, data=email, month=-days
|
||||
).pack(),
|
||||
),
|
||||
)
|
||||
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
|
||||
@@ -173,7 +173,17 @@ async def key_cluster_mode(
|
||||
expiry_time_local = expiry_time.astimezone(moscow_tz)
|
||||
remaining_time = expiry_time_local - datetime.now(moscow_tz)
|
||||
days = remaining_time.days
|
||||
key_message_text = key_message_success(final_link, f"⏳ Осталось дней: {days} 📅")
|
||||
|
||||
tariff_info = None
|
||||
if plan:
|
||||
tariff_info = await get_tariff_by_id(session, plan)
|
||||
|
||||
key_message_text = key_message_success(
|
||||
final_link,
|
||||
tariff_name=tariff_info.get("name", ""),
|
||||
traffic_limit=tariff_info.get("traffic_limit", 0),
|
||||
device_limit=tariff_info.get("device_limit", 0)
|
||||
)
|
||||
|
||||
default_media_path = "img/pic.jpg"
|
||||
if safe_to_edit:
|
||||
|
||||
@@ -545,7 +545,18 @@ async def finalize_key_creation(
|
||||
remaining_time = expiry_time - datetime.now(moscow_tz)
|
||||
days = remaining_time.days
|
||||
link_to_show = public_link or remnawave_link or "Ссылка не найдена"
|
||||
key_message_text = key_message_success(link_to_show, f"⏳ Осталось дней: {days} 📅")
|
||||
|
||||
tariff_info = None
|
||||
if tariff_id:
|
||||
result = await session.execute(select(Tariff).where(Tariff.id == tariff_id))
|
||||
tariff_info = result.scalar_one_or_none()
|
||||
|
||||
key_message_text = key_message_success(
|
||||
link_to_show,
|
||||
tariff_name=tariff_info.name if tariff_info else "",
|
||||
traffic_limit=tariff_info.traffic_limit if tariff_info and tariff_info.traffic_limit is not None else 0,
|
||||
device_limit=tariff_info.device_limit if tariff_info and tariff_info.device_limit is not None else 0
|
||||
)
|
||||
|
||||
await edit_or_send_message(
|
||||
target_message=callback_query.message,
|
||||
|
||||
@@ -11,7 +11,6 @@ from config import (
|
||||
NOTIFY_DELETE_KEY,
|
||||
NOTIFY_HOT_LEADS,
|
||||
NOTIFY_INACTIVE_TRAFFIC,
|
||||
NOTIFY_MAXPRICE,
|
||||
NOTIFY_RENEW,
|
||||
NOTIFY_RENEW_EXPIRED,
|
||||
TRIAL_TIME_DISABLE,
|
||||
@@ -45,10 +44,9 @@ from handlers.texts import (
|
||||
KEY_EXPIRED_NO_DELAY_MSG,
|
||||
KEY_EXPIRY_10H,
|
||||
KEY_EXPIRY_24H,
|
||||
KEY_RENEWED,
|
||||
KEY_RENEWED_TEMP_MSG,
|
||||
get_renewal_message,
|
||||
)
|
||||
from handlers.utils import format_hours, format_minutes
|
||||
from handlers.utils import format_hours, format_minutes, get_russian_month
|
||||
from logger import logger
|
||||
|
||||
from .hot_leads_notifications import notify_hot_leads
|
||||
@@ -404,7 +402,11 @@ async def handle_expired_keys(
|
||||
notification_id,
|
||||
1,
|
||||
"notify_expired.jpg",
|
||||
KEY_RENEWED_TEMP_MSG,
|
||||
get_renewal_message(
|
||||
tariff_name=tariff.get("name", ""),
|
||||
traffic_limit=tariff.get("traffic_limit") if tariff.get("traffic_limit") is not None else 0,
|
||||
device_limit=tariff.get("device_limit") if tariff.get("device_limit") is not None else 0
|
||||
),
|
||||
)
|
||||
continue
|
||||
except Exception as e:
|
||||
@@ -598,6 +600,11 @@ async def process_auto_renew_or_notify(
|
||||
new_expiry_time / 1000, tz=moscow_tz
|
||||
).strftime("%d %B %Y, %H:%M")
|
||||
|
||||
formatted_expiry_date = formatted_expiry_date.replace(
|
||||
datetime.fromtimestamp(new_expiry_time / 1000, tz=moscow_tz).strftime("%B"),
|
||||
get_russian_month(datetime.fromtimestamp(new_expiry_time / 1000, tz=moscow_tz))
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Продление подписки {email} на {duration_days} дней для пользователя {tg_id}. Баланс: {balance}, списываем: {renewal_cost}"
|
||||
)
|
||||
@@ -617,8 +624,11 @@ async def process_auto_renew_or_notify(
|
||||
await add_notification(conn, tg_id, renew_notification_id)
|
||||
await delete_notification(conn, tg_id, notification_id)
|
||||
|
||||
renewed_message = KEY_RENEWED.format(
|
||||
email=email, months=duration_days // 30, expiry_date=formatted_expiry_date
|
||||
renewed_message = get_renewal_message(
|
||||
tariff_name=selected_tariff.get("name", ""),
|
||||
traffic_limit=selected_tariff.get("traffic_limit") if selected_tariff.get("traffic_limit") is not None else 0,
|
||||
device_limit=selected_tariff.get("device_limit") if selected_tariff.get("device_limit") is not None else 0,
|
||||
expiry_date=formatted_expiry_date
|
||||
)
|
||||
|
||||
keyboard = build_notification_expired_kb()
|
||||
|
||||
Reference in New Issue
Block a user