From 6e3b33e335c365fce8cb9220c7b2eeab69fedfc9 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Mon, 31 Mar 2025 00:57:13 +0300 Subject: [PATCH 1/5] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=B8=D1=87=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Добавление личного рейтинга вне зависимости от топа. --- handlers/profile.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/handlers/profile.py b/handlers/profile.py index 85b1458d..82fe9ea3 100644 --- a/handlers/profile.py +++ b/handlers/profile.py @@ -294,6 +294,28 @@ async def inline_referral_handler(inline_query: InlineQuery): async def top_referrals_handler(callback_query: CallbackQuery): conn = await asyncpg.connect(DATABASE_URL) try: + user_referral_count = await conn.fetchval( + "SELECT COUNT(*) FROM referrals WHERE referrer_tg_id = $1", + callback_query.from_user.id + ) or 0 + + personal_block = "Твоё место в рейтинге:\n" + if user_referral_count > 0: + user_position = await conn.fetchval( + """ + SELECT COUNT(*) + 1 FROM ( + SELECT COUNT(*) as cnt + FROM referrals + GROUP BY referrer_tg_id + HAVING COUNT(*) > $1 + ) AS better_users + """, + user_referral_count + ) + personal_block += f"{user_position}. {callback_query.from_user.id} - {user_referral_count} чел." + else: + personal_block += "Ты еще не приглашал пользователей в проект." + top_referrals = await conn.fetch( """ SELECT referrer_tg_id, COUNT(*) as referral_count @@ -306,14 +328,13 @@ async def top_referrals_handler(callback_query: CallbackQuery): is_admin = callback_query.from_user.id in ADMIN_ID rows = "" - for i, row in enumerate(top_referrals, 1): tg_id = str(row["referrer_tg_id"]) count = row["referral_count"] display_id = tg_id if is_admin else f"{tg_id[:5]}*****" rows += f"{i}. {display_id} - {count} чел.\n" - text = TOP_REFERRALS_TEXT.format(rows=rows) + text = TOP_REFERRALS_TEXT.format(personal_block=personal_block, rows=rows) builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text=BACK, callback_data="invite")) From 6d42647bf64dc544fe9193721a77d60cc33346f6 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Mon, 31 Mar 2025 22:01:59 +0300 Subject: [PATCH 2/5] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BA?= =?UTF-8?q?=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Добавлены кнопки скачать win/macos - Добавлены кнопки выбора устройств win/macos --- handlers/buttons.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/handlers/buttons.py b/handlers/buttons.py index c0032a80..7bd83484 100644 --- a/handlers/buttons.py +++ b/handlers/buttons.py @@ -45,14 +45,16 @@ CANCEL = "❌ Отмена" DOWNLOAD_IOS_BUTTON = "🍏 Скачать iOS" DOWNLOAD_ANDROID_BUTTON = "🤖 Скачать Android" +DOWNLOAD_MACOS_BUTTON = "🍏 Скачать macOS" +DOWNLOAD_PC_BUTTON = "💻 Скачать Windows" IMPORT_IOS = "🍏 Подключить" IMPORT_ANDROID = "🤖 Подключить" PC_BUTTON = "💻 Компьютеры" TV_BUTTON = "📺 Андроид TV" CONNECT_PHONE = "📱 Подключить телефон" CONNECT_DEVICE = "📲 Подключить устройство" -CONNECT_WINDOWS_BUTTON = "💻 Подключить Windows" -CONNECT_MACOS_BUTTON = "💻 Подключить MacOS" +CONNECT_WINDOWS_BUTTON = "💻 Подключить" +CONNECT_MACOS_BUTTON = "🍏 Подключить" ALIAS = "✏️" UNFREEZE = "🟢 Разморозить подписку" FREEZE = "🛑 Заморозить подписку" @@ -64,6 +66,8 @@ QR = "📷 Показать QR-код" IPHONE = "🍏 Айфон" ANDROID = "🤖 Андроид" PC = "💻 Компьютер" +PC_PC = "💻 Windows" +PC_MACOS = "🍏 macOS" TV = "📺 Телевизор" ROUTER = "📶 Роутер" MANUAL_INSTRUCTIONS = "📖 Ручная установка" From fcb6dd97738adc6c925a53fe56edc9f6c81fe198 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Mon, 31 Mar 2025 22:04:33 +0300 Subject: [PATCH 3/5] =?UTF-8?q?=D0=A7=D0=B0=D1=81=D1=82=D1=8C=20=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=D1=82=D0=B0=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=81=D0=B0=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Часть текста перенесена CHOOSE_DEVICE_TEXT --- handlers/keys/keys.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/handlers/keys/keys.py b/handlers/keys/keys.py index f9d804de..2e85766f 100644 --- a/handlers/keys/keys.py +++ b/handlers/keys/keys.py @@ -87,6 +87,7 @@ from handlers.payments.robokassa_pay import handle_custom_amount_input from handlers.payments.yookassa_pay import process_custom_amount_input from handlers.texts import ( ANDROID_DESCRIPTION_TEMPLATE, + CHOOSE_DEVICE_TEXT, DELETE_KEY_CONFIRM_MSG, DISCOUNTS, FREEZE_SUBSCRIPTION_CONFIRM_MSG, @@ -420,7 +421,7 @@ async def handle_connect_device(callback_query: CallbackQuery): await edit_or_send_message( target_message=callback_query.message, - text="📲 Выберите устройство, которое хотите подключить:", + text=CHOOSE_DEVICE_TEXT, reply_markup=builder.as_markup(), media_path=None, ) From 3920992cee912b91b5a93881dd45ca7d78761f06 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Mon, 31 Mar 2025 22:08:27 +0300 Subject: [PATCH 4/5] =?UTF-8?q?=D0=92=D1=8B=D0=B1=D0=BE=D1=80=20win/macOS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Сделан выбор win/macOS - Сделаны текста для них отдельные. --- handlers/instructions/instructions.py | 62 ++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/handlers/instructions/instructions.py b/handlers/instructions/instructions.py index f436d7fc..22545e69 100644 --- a/handlers/instructions/instructions.py +++ b/handlers/instructions/instructions.py @@ -1,5 +1,4 @@ import os - from typing import Any from aiogram import F, Router @@ -10,20 +9,32 @@ from aiogram.types import ( ) from aiogram.utils.keyboard import InlineKeyboardBuilder -from config import CONNECT_MACOS, CONNECT_WINDOWS, SUPPORT_CHAT_URL +from config import ( + CONNECT_MACOS, + CONNECT_WINDOWS, + DOWNLOAD_MACOS, + DOWNLOAD_PC, + SUPPORT_CHAT_URL, +) from database import get_key_details from handlers.buttons import ( BACK, CONNECT_MACOS_BUTTON, CONNECT_WINDOWS_BUTTON, + DOWNLOAD_MACOS_BUTTON, + DOWNLOAD_PC_BUTTON, MAIN_MENU, + PC_MACOS, + PC_PC, SUPPORT, TV_CONTINUE, TV_INSTRUCTIONS, ) from handlers.texts import ( + CHOOSE_DEVICE_TEXT, CONNECT_TV_TEXT, INSTRUCTIONS, + INSTRUCTION_MACOS, INSTRUCTION_PC, KEY_MESSAGE, SUBSCRIPTION_DETAILS_TEXT, @@ -72,16 +83,54 @@ async def process_connect_pc(callback_query: CallbackQuery, session: Any): ) return + builder = InlineKeyboardBuilder() + builder.row(InlineKeyboardButton(text=PC_PC, callback_data=f"windows_menu|{key_name}")) + builder.row(InlineKeyboardButton(text=PC_MACOS, callback_data=f"macos_menu|{key_name}")) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) + + await edit_or_send_message( + target_message=callback_query.message, + text=CHOOSE_DEVICE_TEXT, + reply_markup=builder.as_markup(), + media_path=None, + ) + + +@router.callback_query(F.data.startswith("windows_menu|")) +async def process_windows_menu(callback_query: CallbackQuery, session: Any): + key_name = callback_query.data.split("|")[1] + record = await get_key_details(key_name, session) key = record["key"] key_message_text = KEY_MESSAGE.format(key) instruction_message = f"{key_message_text}{INSTRUCTION_PC}" builder = InlineKeyboardBuilder() + builder.row(InlineKeyboardButton(text=DOWNLOAD_PC_BUTTON, url=DOWNLOAD_PC)) builder.row(InlineKeyboardButton(text=CONNECT_WINDOWS_BUTTON, url=f"{CONNECT_WINDOWS}{key}")) + builder.row(InlineKeyboardButton(text=SUPPORT, url=SUPPORT_CHAT_URL)) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_pc|{key_name}")) + + await edit_or_send_message( + target_message=callback_query.message, + text=instruction_message, + reply_markup=builder.as_markup(), + media_path=None, + ) + + +@router.callback_query(F.data.startswith("macos_menu|")) +async def process_macos_menu(callback_query: CallbackQuery, session: Any): + key_name = callback_query.data.split("|")[1] + record = await get_key_details(key_name, session) + key = record["key"] + key_message_text = KEY_MESSAGE.format(key) + instruction_message = f"{key_message_text}{INSTRUCTION_MACOS}" + + builder = InlineKeyboardBuilder() + builder.row(InlineKeyboardButton(text=DOWNLOAD_MACOS_BUTTON, url=DOWNLOAD_MACOS)) builder.row(InlineKeyboardButton(text=CONNECT_MACOS_BUTTON, url=f"{CONNECT_MACOS}{key}")) builder.row(InlineKeyboardButton(text=SUPPORT, url=SUPPORT_CHAT_URL)) - builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) - builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_pc|{key_name}")) await edit_or_send_message( target_message=callback_query.message, @@ -123,5 +172,8 @@ async def process_continue_tv(callback_query: CallbackQuery, session: Any): builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) await edit_or_send_message( - target_message=callback_query.message, text=message_text, reply_markup=builder.as_markup(), media_path=None + target_message=callback_query.message, + text=message_text, + reply_markup=builder.as_markup(), + media_path=None, ) From f9e404a7c2513c48f27728b74f23382cdb643447 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Tue, 1 Apr 2025 00:01:44 +0300 Subject: [PATCH 5/5] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -правка текста --- handlers/admin/stats/stats_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/admin/stats/stats_handler.py b/handlers/admin/stats/stats_handler.py index 5ee43ab4..b2efe1df 100644 --- a/handlers/admin/stats/stats_handler.py +++ b/handlers/admin/stats/stats_handler.py @@ -121,7 +121,7 @@ async def handle_stats(callback_query: CallbackQuery, session: Any): f"├ 📆 За неделю: {total_payments_week} ₽\n" f"├ 📆 За месяц: {total_payments_month} ₽\n" f"└ 🏦 Всего: {total_payments_all_time} ₽\n\n" - f"🔥 Горящие лиды: {hot_leads_count} (платили, но не активировали ключи)\n\n" + f"🔥 Горящие лиды: {hot_leads_count} (платили, но не продлили)\n\n" f"⏱️ Последнее обновление: {update_time}" )