Полная реструктуризация. Тексты все в texts.py

This commit is contained in:
Vladless
2024-10-27 03:16:58 +03:00
parent 7512868219
commit 16561610b6
19 changed files with 95 additions and 71 deletions
+2 -1
View File
@@ -8,4 +8,5 @@
/database.db /database.db
/backup_pg.sh /backup_pg.sh
/config copy.py /config copy.py
/docker-compose.yml /docker-compose.yml
__pycache__
+4 -3
View File
@@ -8,8 +8,10 @@ storage = MemoryStorage()
dp = Dispatcher(bot=bot, storage=storage) dp = Dispatcher(bot=bot, storage=storage)
router = Router() router = Router()
from handlers import (backup_handler, key_management, keys, notifications, pay, from handlers.admin import admin
profile, start, admin, commands) from handlers.keys import key_management, keys
from handlers import (notifications, pay,
profile, start, commands)
dp.include_router(commands.router) dp.include_router(commands.router)
dp.include_router(start.router) dp.include_router(start.router)
@@ -18,5 +20,4 @@ dp.include_router(keys.router)
dp.include_router(key_management.router) dp.include_router(key_management.router)
dp.include_router(pay.router) dp.include_router(pay.router)
dp.include_router(notifications.router) dp.include_router(notifications.router)
dp.include_router(backup_handler.router)
dp.include_router(admin.router) dp.include_router(admin.router)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
from aiogram import Router, types from aiogram import Router, types
from aiogram.filters import Command from aiogram.filters import Command
from database import add_balance_to_client, get_balance, check_connection_exists # Импорт необходимых функций from database import add_balance_to_client, get_balance, check_connection_exists
from config import ADMIN_ID from config import ADMIN_ID
router = Router() router = Router()
-17
View File
@@ -1,17 +0,0 @@
from aiogram import Router
from aiogram.filters import Command
from aiogram.types import Message
from config import ADMIN_ID
router = Router()
@router.message(Command('backup'))
async def backup_command(message: Message):
if message.from_user.id != ADMIN_ID:
await message.answer("У вас нет прав для выполнения этой команды.")
return
from backup import backup_database
await message.answer("Запускаю бэкап базы данных...")
await backup_database()
await message.answer("Бэкап завершен и отправлен админу.")
+14 -3
View File
@@ -6,13 +6,13 @@ import asyncpg
from bot import bot from bot import bot
from config import ADMIN_ID, DATABASE_URL from config import ADMIN_ID, DATABASE_URL
from handlers.backup_handler import backup_command
from handlers.pay import ReplenishBalanceState, process_custom_amount_input from handlers.pay import ReplenishBalanceState, process_custom_amount_input
from handlers.profile import process_callback_view_profile from handlers.profile import process_callback_view_profile
from handlers.start import start_command from handlers.start import start_command
from handlers.texts import TRIAL from handlers.texts import TRIAL
from handlers.admin import cmd_add_balance from handlers.admin.admin import cmd_add_balance
from handlers.key_management import handle_key_name_input from handlers.keys.key_management import handle_key_name_input
from aiogram.types import Message
router = Router() router = Router()
@@ -22,6 +22,17 @@ class Form(StatesGroup):
viewing_profile = State() viewing_profile = State()
waiting_for_message = State() waiting_for_message = State()
@router.message(Command('backup'))
async def backup_command(message: Message):
if message.from_user.id != ADMIN_ID:
await message.answer("У вас нет прав для выполнения этой команды.")
return
from backup import backup_database
await message.answer("Запускаю бэкап базы данных...")
await backup_database()
await message.answer("Бэкап завершен и отправлен админу.")
@router.message(Command('start')) @router.message(Command('start'))
async def handle_start(message: types.Message, state: FSMContext): async def handle_start(message: types.Message, state: FSMContext):
await start_command(message) await start_command(message)

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

@@ -1,6 +1,7 @@
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from bot import dp
import asyncpg import asyncpg
from aiogram import F, Router from aiogram import F, Router
from aiogram.fsm.context import FSMContext from aiogram.fsm.context import FSMContext
@@ -9,12 +10,11 @@ from aiogram.types import (CallbackQuery, InlineKeyboardButton,
InlineKeyboardMarkup, Message) InlineKeyboardMarkup, Message)
from auth import link, login_with_credentials from auth import link, login_with_credentials
from bot import bot, dp
from client import add_client from client import add_client
from config import (ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, from config import (ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL,
SERVERS) SERVERS)
from database import add_connection, get_balance, store_key, update_balance from database import add_connection, get_balance, store_key, update_balance
from handlers.instructions import send_instructions from handlers.instructions.instructions import send_instructions
from handlers.profile import process_callback_view_profile from handlers.profile import process_callback_view_profile
from handlers.texts import KEY, KEY_TRIAL, NULL_BALANCE, key_message_success from handlers.texts import KEY, KEY_TRIAL, NULL_BALANCE, key_message_success
from handlers.utils import sanitize_key_name from handlers.utils import sanitize_key_name
@@ -121,7 +121,7 @@ async def handle_key_name_input(message: Message, state: FSMContext):
key_name = sanitize_key_name(message.text) key_name = sanitize_key_name(message.text)
if not key_name: if not key_name:
await message.bot.send_message(tg_id, "📝 Пожалуйста, назовите профиль на английском языке.") await message.bot.send_message(tg_id, "📝 Пожалуйста, назовите ключ устройства на английском языке.")
return return
data = await state.get_data() data = await state.get_data()
@@ -164,7 +164,7 @@ async def handle_key_name_input(message: Message, state: FSMContext):
if not response.get("success", True): if not response.get("success", True):
error_msg = response.get("msg", "Неизвестная ошибка.") error_msg = response.get("msg", "Неизвестная ошибка.")
if "Duplicate email" in error_msg: if "Duplicate email" in error_msg:
await message.bot.send_message(tg_id, "❌ Этот email уже используется. Пожалуйста, выберите другое имя для ключа.") await message.bot.send_message(tg_id, "❌ Это имя уже используется. Пожалуйста, выберите другое имя для ключа.")
await state.set_state(Form.waiting_for_key_name) await state.set_state(Form.waiting_for_key_name)
return return
else: else:
+14 -21
View File
@@ -11,6 +11,7 @@ from config import ADMIN_PASSWORD, ADMIN_USERNAME, DATABASE_URL, SERVERS
from database import get_balance, update_balance from database import get_balance, update_balance
from handlers.texts import NO_KEYS from handlers.texts import NO_KEYS
from handlers.texts import key_message, key_relocated from handlers.texts import key_message, key_relocated
from handlers.texts import RENEWAL_PLANS, INSUFFICIENT_FUNDS_MSG, KEY_NOT_FOUND_MSG, SUCCESS_RENEWAL_MSG, ERROR_RENEWAL_MSG, PLAN_SELECTION_MSG
locale.setlocale(locale.LC_TIME, 'ru_RU.UTF-8') locale.setlocale(locale.LC_TIME, 'ru_RU.UTF-8')
@@ -159,17 +160,15 @@ async def process_callback_renew_key(callback_query: types.CallbackQuery):
expiry_time = record['expiry_time'] expiry_time = record['expiry_time']
current_time = datetime.utcnow().timestamp() * 1000 current_time = datetime.utcnow().timestamp() * 1000
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[ keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
[types.InlineKeyboardButton(text='📅 1 месяц (100 руб.)', callback_data=f'renew_plan|1|{client_id}')], [types.InlineKeyboardButton(text=f'📅 1 месяц ({RENEWAL_PLANS["1"]["price"]} руб.)', callback_data=f'renew_plan|1|{client_id}')],
[types.InlineKeyboardButton(text='📅 3 месяца (285 руб.)', callback_data=f'renew_plan|3|{client_id}')], [types.InlineKeyboardButton(text=f'📅 3 месяца ({RENEWAL_PLANS["3"]["price"]} руб.)', callback_data=f'renew_plan|3|{client_id}')],
[types.InlineKeyboardButton(text='📅 6 месяцев (540 руб.)', callback_data=f'renew_plan|6|{client_id}')], [types.InlineKeyboardButton(text=f'📅 6 месяцев ({RENEWAL_PLANS["6"]["price"]} руб.)', callback_data=f'renew_plan|6|{client_id}')],
[types.InlineKeyboardButton(text='📅 12 месяцев (1000 руб.)', callback_data=f'renew_plan|12|{client_id}')], [types.InlineKeyboardButton(text=f'📅 12 месяцев ({RENEWAL_PLANS["12"]["price"]} руб.)', callback_data=f'renew_plan|12|{client_id}')],
[types.InlineKeyboardButton(text='🔙 Назад', callback_data='view_profile')] [types.InlineKeyboardButton(text='🔙 Назад', callback_data='view_profile')]
]) ])
balance = await get_balance(tg_id) balance = await get_balance(tg_id)
response_message = (f"<b>Выберите план продления:</b>\n\n" response_message = PLAN_SELECTION_MSG.format(balance=balance, expiry_date=datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S'))
f"💰 <b>Баланс:</b> {balance} руб.\n\n"
f"📅 <b>Текущая дата истечения ключа:</b> {datetime.utcfromtimestamp(expiry_time / 1000).strftime('%Y-%m-%d %H:%M:%S')}")
await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard, parse_mode="HTML") await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard, parse_mode="HTML")
@@ -181,6 +180,7 @@ async def process_callback_renew_key(callback_query: types.CallbackQuery):
await callback_query.answer() await callback_query.answer()
@router.callback_query(lambda c: c.data.startswith('confirm_delete|')) @router.callback_query(lambda c: c.data.startswith('confirm_delete|'))
async def process_callback_confirm_delete(callback_query: types.CallbackQuery): async def process_callback_confirm_delete(callback_query: types.CallbackQuery):
tg_id = callback_query.from_user.id tg_id = callback_query.from_user.id
@@ -222,7 +222,7 @@ async def process_callback_confirm_delete(callback_query: types.CallbackQuery):
@router.callback_query(lambda c: c.data.startswith('renew_plan|')) @router.callback_query(lambda c: c.data.startswith('renew_plan|'))
async def process_callback_renew_plan(callback_query: types.CallbackQuery): async def process_callback_renew_plan(callback_query: types.CallbackQuery):
tg_id = callback_query.from_user.id tg_id = callback_query.from_user.id
plan, client_id = callback_query.data.split('|')[1], callback_query.data.split('|')[2] plan, client_id = callback_query.data.split('|')[1], callback_query.data.split('|')[2]
days_to_extend = 30 * int(plan) days_to_extend = 30 * int(plan)
try: try:
@@ -241,14 +241,7 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery):
else: else:
new_expiry_time = int(expiry_time + timedelta(days=days_to_extend).total_seconds() * 1000) new_expiry_time = int(expiry_time + timedelta(days=days_to_extend).total_seconds() * 1000)
if plan == '1': cost = RENEWAL_PLANS[plan]['price']
cost = 100
elif plan == '3':
cost = 285
elif plan == '6':
cost = 540
elif plan == '12':
cost = 1000
balance = await get_balance(tg_id) balance = await get_balance(tg_id)
if balance < cost: if balance < cost:
@@ -256,7 +249,7 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery):
back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_profile') back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_profile')
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[replenish_button], [back_button]]) keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[replenish_button], [back_button]])
await bot.edit_message_text("Недостаточно средств для продления ключа.", chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard) await bot.edit_message_text(INSUFFICIENT_FUNDS_MSG, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard)
return return
session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD) session = await login_with_credentials(server_id, ADMIN_USERNAME, ADMIN_PASSWORD)
@@ -265,14 +258,14 @@ async def process_callback_renew_plan(callback_query: types.CallbackQuery):
if success: if success:
await update_balance(tg_id, -cost) await update_balance(tg_id, -cost)
await conn.execute('UPDATE keys SET expiry_time = $1 WHERE client_id = $2', new_expiry_time, client_id) await conn.execute('UPDATE keys SET expiry_time = $1 WHERE client_id = $2', new_expiry_time, client_id)
response_message = f"Ваш ключ был успешно продлен на {days_to_extend // 30} месяц(-а)." response_message = SUCCESS_RENEWAL_MSG.format(months=RENEWAL_PLANS[plan]['months'])
back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_profile') back_button = types.InlineKeyboardButton(text='Назад', callback_data='view_profile')
keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[back_button]]) keyboard = types.InlineKeyboardMarkup(inline_keyboard=[[back_button]])
await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard) await bot.edit_message_text(response_message, chat_id=tg_id, message_id=callback_query.message.message_id, reply_markup=keyboard)
else: else:
await bot.edit_message_text("Ошибка при продлении ключа.", chat_id=tg_id, message_id=callback_query.message.message_id) await bot.edit_message_text(ERROR_RENEWAL_MSG, chat_id=tg_id, message_id=callback_query.message.message_id)
else: else:
await bot.edit_message_text("Ключ не найден.", chat_id=tg_id, message_id=callback_query.message.message_id) await bot.edit_message_text(KEY_NOT_FOUND_MSG, chat_id=tg_id, message_id=callback_query.message.message_id)
finally: finally:
await conn.close() await conn.close()
@@ -294,7 +287,7 @@ async def process_callback_change_location(callback_query: types.CallbackQuery):
try: try:
for server_id, server in SERVERS.items(): for server_id, server in SERVERS.items():
count = await conn.fetchval('SELECT COUNT(*) FROM keys WHERE server_id = $1', server_id) count = await conn.fetchval('SELECT COUNT(*) FROM keys WHERE server_id = $1', server_id)
percent_full = (count / 100) * 100 percent_full = (count / 60) * 100 if count <= 60 else 100
server_name = f"{server['name']} ({percent_full:.1f}%)" server_name = f"{server['name']} ({percent_full:.1f}%)"
server_buttons.append([types.InlineKeyboardButton(text=server_name, callback_data=f'select_server&{server_id}&{client_id}')]) server_buttons.append([types.InlineKeyboardButton(text=server_name, callback_data=f'select_server&{server_id}&{client_id}')])
finally: finally:
@@ -1,4 +1,3 @@
import random
import asyncpg import asyncpg
import uuid import uuid
from config import DATABASE_URL, SERVERS, ADMIN_USERNAME, ADMIN_PASSWORD from config import DATABASE_URL, SERVERS, ADMIN_USERNAME, ADMIN_PASSWORD
+20 -9
View File
@@ -13,6 +13,7 @@ from config import YOOKASSA_SECRET_KEY, YOOKASSA_SHOP_ID
from database import (add_connection, check_connection_exists, get_key_count, from database import (add_connection, check_connection_exists, get_key_count,
update_balance) update_balance)
from handlers.profile import process_callback_view_profile from handlers.profile import process_callback_view_profile
from handlers.texts import PAYMENT_OPTIONS
router = Router() router = Router()
@@ -59,10 +60,20 @@ async def process_callback_replenish_balance(callback_query: types.CallbackQuery
await add_connection(tg_id, balance=0.0, trial=0) await add_connection(tg_id, balance=0.0, trial=0)
amount_keyboard = InlineKeyboardMarkup(inline_keyboard=[ amount_keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='100 RUB', callback_data='amount_100'), InlineKeyboardButton(text='300 RUB', callback_data='amount_300')], [
[InlineKeyboardButton(text='600 RUB', callback_data='amount_600'), InlineKeyboardButton(text='1000 RUB', callback_data='amount_1000')], InlineKeyboardButton(text=PAYMENT_OPTIONS[0]['text'], callback_data=PAYMENT_OPTIONS[0]['callback_data']),
[InlineKeyboardButton(text='💰 Ввести свою сумму', callback_data='enter_custom_amount')], InlineKeyboardButton(text=PAYMENT_OPTIONS[1]['text'], callback_data=PAYMENT_OPTIONS[1]['callback_data'])
[InlineKeyboardButton(text='⬅️ Назад', callback_data='back_to_profile')] ],
[
InlineKeyboardButton(text=PAYMENT_OPTIONS[2]['text'], callback_data=PAYMENT_OPTIONS[2]['callback_data']),
InlineKeyboardButton(text=PAYMENT_OPTIONS[3]['text'], callback_data=PAYMENT_OPTIONS[3]['callback_data'])
],
[
InlineKeyboardButton(text=PAYMENT_OPTIONS[4]['text'], callback_data=PAYMENT_OPTIONS[4]['callback_data'])
],
[
InlineKeyboardButton(text=PAYMENT_OPTIONS[5]['text'], callback_data=PAYMENT_OPTIONS[5]['callback_data'])
]
]) ])
await callback_query.message.edit_text( await callback_query.message.edit_text(
@@ -72,6 +83,7 @@ async def process_callback_replenish_balance(callback_query: types.CallbackQuery
await state.set_state(ReplenishBalanceState.choosing_amount) await state.set_state(ReplenishBalanceState.choosing_amount)
await callback_query.answer() await callback_query.answer()
@router.callback_query(lambda c: c.data == 'back_to_profile') @router.callback_query(lambda c: c.data == 'back_to_profile')
async def back_to_profile_handler(callback_query: types.CallbackQuery, state: FSMContext): async def back_to_profile_handler(callback_query: types.CallbackQuery, state: FSMContext):
await process_callback_view_profile(callback_query, state) await process_callback_view_profile(callback_query, state)
@@ -126,9 +138,6 @@ async def process_amount_selection(callback_query: types.CallbackQuery, state: F
"currency": "RUB" "currency": "RUB"
}, },
"vat_code": 6 "vat_code": 6
## Раскоментируйте следующие строки, если у вас регистрация как ИП, а не самозанятость
## "payment_subject": "payment",
## "payment_mode": "full_payment",
} }
] ]
}, },
@@ -260,7 +269,9 @@ async def process_custom_amount_input(message: types.Message, state: FSMContext)
) )
else: else:
await message.answer("Ошибка при создании платежа.") await message.answer("Ошибка при создании платежа.")
except Exception as e: except Exception as e:
await message.answer(f"Произошла ошибка при обработке платежа: {str(e)}") logging.error(f"Ошибка при создании платежа: {e}")
await message.answer("Произошла ошибка при создании платежа.")
else: else:
await message.answer("Некорректный ввод. Пожалуйста, введите сумму числом:") await message.answer("Некорректная сумма. Пожалуйста, введите сумму еще раз:")
+5 -4
View File
@@ -5,7 +5,7 @@ from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from bot import bot from bot import bot
from database import get_balance, get_key_count, get_referral_stats from database import get_balance, get_key_count, get_referral_stats
from handlers.texts import profile_message_send, invite_message_send from handlers.texts import profile_message_send, invite_message_send, CHANNEL_LINK, get_referral_link
class ReplenishBalanceState(StatesGroup): class ReplenishBalanceState(StatesGroup):
@@ -13,6 +13,7 @@ class ReplenishBalanceState(StatesGroup):
waiting_for_admin_confirmation = State() waiting_for_admin_confirmation = State()
router = Router() router = Router()
async def process_callback_view_profile(callback_query: types.CallbackQuery, state: FSMContext): async def process_callback_view_profile(callback_query: types.CallbackQuery, state: FSMContext):
tg_id = callback_query.from_user.id tg_id = callback_query.from_user.id
username = callback_query.from_user.full_name username = callback_query.from_user.full_name
@@ -28,7 +29,7 @@ async def process_callback_view_profile(callback_query: types.CallbackQuery, sta
) )
profile_message += ( profile_message += (
f"<b>Обязательно подпишитесь на канал</b> <a href='https://t.me/solonet_vpn'>здесь</a>\n" f"<b>Обязательно подпишитесь на канал</b> <a href='{CHANNEL_LINK}'>здесь</a>\n"
) )
if key_count == 0: if key_count == 0:
@@ -66,7 +67,7 @@ async def process_callback_view_profile(callback_query: types.CallbackQuery, sta
@router.callback_query(lambda c: c.data == 'invite') @router.callback_query(lambda c: c.data == 'invite')
async def invite_handler(callback_query: types.CallbackQuery): async def invite_handler(callback_query: types.CallbackQuery):
tg_id = callback_query.from_user.id tg_id = callback_query.from_user.id
referral_link = f"https://t.me/SoloNetVPN_bot?start=referral_{tg_id}" referral_link = get_referral_link(tg_id)
referral_stats = await get_referral_stats(tg_id) referral_stats = await get_referral_stats(tg_id)
@@ -90,4 +91,4 @@ async def invite_handler(callback_query: types.CallbackQuery):
@router.callback_query(lambda c: c.data == 'view_profile') @router.callback_query(lambda c: c.data == 'view_profile')
async def view_profile_handler(callback_query: types.CallbackQuery, state: FSMContext): async def view_profile_handler(callback_query: types.CallbackQuery, state: FSMContext):
await process_callback_view_profile(callback_query, state) await process_callback_view_profile(callback_query, state)
+1 -5
View File
@@ -8,7 +8,7 @@ from handlers.texts import ABOUT_VPN, WELCOME_TEXT
from bot import bot from bot import bot
from config import CHANNEL_URL, SUPPORT_CHAT_URL from config import CHANNEL_URL, SUPPORT_CHAT_URL
from database import add_connection, add_referral, check_connection_exists, get_trial from database import add_connection, add_referral, check_connection_exists, get_trial
from handlers.trial_key import create_trial_key from handlers.keys.trial_key import create_trial_key
from handlers.texts import INSTRUCTIONS_TRIAL from handlers.texts import INSTRUCTIONS_TRIAL
router = Router() router = Router()
@@ -65,23 +65,19 @@ async def handle_connect_vpn(callback_query: CallbackQuery):
await callback_query.message.delete() await callback_query.message.delete()
user_id = callback_query.from_user.id user_id = callback_query.from_user.id
# Создаём триальный ключ
trial_key_info = await create_trial_key(user_id) trial_key_info = await create_trial_key(user_id)
if 'error' in trial_key_info: if 'error' in trial_key_info:
await callback_query.message.answer(trial_key_info['error']) await callback_query.message.answer(trial_key_info['error'])
else: else:
# Формируем сообщение с ключом и инструкциями
key_message = ( key_message = (
f"<b>Ваш ключ доступа:</b>\n<pre>{trial_key_info['key']}</pre>\n\n" f"<b>Ваш ключ доступа:</b>\n<pre>{trial_key_info['key']}</pre>\n\n"
f"<b>Инструкции:</b>\n{INSTRUCTIONS_TRIAL}" f"<b>Инструкции:</b>\n{INSTRUCTIONS_TRIAL}"
) )
# Кнопка "В профиль"
button_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile') button_profile = InlineKeyboardButton(text='👤 Мой профиль', callback_data='view_profile')
inline_keyboard_profile = InlineKeyboardMarkup(inline_keyboard=[[button_profile]]) inline_keyboard_profile = InlineKeyboardMarkup(inline_keyboard=[[button_profile]])
# Отправляем текст с ключом и инструкциями в виде цитаты
await callback_query.message.answer( await callback_query.message.answer(
key_message, key_message,
parse_mode='HTML', parse_mode='HTML',
+30 -2
View File
@@ -1,5 +1,29 @@
from config import BOT_VERSION BOT_VERSION = '1.3.2'
### Функции образования цен и кнопок продления ключа
PAYMENT_OPTIONS = [
{'text': '100 RUB', 'callback_data': 'amount_100'},
{'text': '300 RUB', 'callback_data': 'amount_300'},
{'text': '600 RUB', 'callback_data': 'amount_600'},
{'text': '1000 RUB', 'callback_data': 'amount_1000'},
{'text': '💰 Ввести свою сумму', 'callback_data': 'enter_custom_amount'},
{'text': '⬅️ Назад', 'callback_data': 'back_to_profile'},
]
RENEWAL_PLANS = {
'1': {'months': 1, 'price': 100},
'3': {'months': 3, 'price': 285},
'6': {'months': 6, 'price': 540},
'12': {'months': 12, 'price': 1000},
}
INSUFFICIENT_FUNDS_MSG = "Недостаточно средств для продления ключа."
KEY_NOT_FOUND_MSG = "Ключ не найден."
SUCCESS_RENEWAL_MSG = "Ваш ключ был успешно продлен на {months} месяц(-а)."
ERROR_RENEWAL_MSG = "Ошибка при продлении ключа."
PLAN_SELECTION_MSG = "<b>Выберите план продления:</b>\n\n💰 <b>Баланс:</b> {balance} руб.\n\n📅 <b>Текущая дата истечения ключа:</b> {expiry_date}"
### Текст главного меню
WELCOME_TEXT = ( WELCOME_TEXT = (
"<b>🎉 SoloNet — твой доступ в свободный интернет! 🌐✨</b>\n\n" "<b>🎉 SoloNet — твой доступ в свободный интернет! 🌐✨</b>\n\n"
"<b>Наши преимущества:</b>\n" "<b>Наши преимущества:</b>\n"
@@ -80,7 +104,6 @@ INSTRUCTIONS_TRIAL = (
"💬 Если у вас возникнут вопросы, не стесняйтесь обращаться в <a href='https://t.me/solonet_sup'>поддержку</a>." "💬 Если у вас возникнут вопросы, не стесняйтесь обращаться в <a href='https://t.me/solonet_sup'>поддержку</a>."
) )
KEY_EXPIRY_10H = "🔔 Уведомление: Ваш ключ {email} для сервера {server_id} истекает через 10 часов.\n" \ KEY_EXPIRY_10H = "🔔 Уведомление: Ваш ключ {email} для сервера {server_id} истекает через 10 часов.\n" \
"Дата истечения: {expiry_date}"\ "Дата истечения: {expiry_date}"\
"Перейдите в профиль и пополните баланс, всего 100 рублей на целый месяц"\ "Перейдите в профиль и пополните баланс, всего 100 рублей на целый месяц"\
@@ -96,6 +119,11 @@ KEY_RENEWAL_FAILED = "Не удалось продлить ключ на пан
KEY_DELETED = "Ваш ключ был удален из-за недостаточного баланса." KEY_DELETED = "Ваш ключ был удален из-за недостаточного баланса."
KEY_DELETION_FAILED = "Не удалось удалить ключ с панели, обратитесь в поддержку." KEY_DELETION_FAILED = "Не удалось удалить ключ с панели, обратитесь в поддержку."
CHANNEL_LINK = "https://t.me/solonet_vpn"
def get_referral_link(user_id):
return f"https://t.me/SoloNetVPN_bot?start=referral_{user_id}"
def key_message_success(connection_link, remaining_time_message): def key_message_success(connection_link, remaining_time_message):
key_message = ( key_message = (
"✅ Ключ успешно создан:\n" "✅ Ключ успешно создан:\n"