Optimize and fix imports

This commit is contained in:
hteppl
2025-03-25 17:42:53 +03:00
parent ece35bb90a
commit ff591fc387
40 changed files with 61 additions and 113 deletions
+1 -3
View File
@@ -1,15 +1,13 @@
import os
import subprocess
from datetime import datetime, timedelta
from pathlib import Path
import aiofiles
from aiogram.types import BufferedInputFile
from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER, PG_HOST, PG_PORT
from bot import bot
from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER, PG_HOST, PG_PORT
from logger import logger
+1 -2
View File
@@ -8,13 +8,12 @@ from aiogram.filters import ExceptionTypeFilter
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.types import BufferedInputFile, ErrorEvent
from aiogram.utils.markdown import hbold
from config import ADMIN_ID, API_TOKEN
from config import ADMIN_ID, API_TOKEN
from filters.private import IsPrivateFilter
from logger import logger
from middlewares import register_middleware
bot = Bot(token=API_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
storage = MemoryStorage()
dp = Dispatcher(bot=bot, storage=storage)
-1
View File
@@ -5,7 +5,6 @@ import httpx
import py3xui
from config import LIMIT_IP, SUPERNODE
from logger import logger
-2
View File
@@ -1,5 +1,4 @@
import json
from datetime import datetime
from typing import Any
@@ -7,7 +6,6 @@ import asyncpg
import pytz
from config import CASHBACK, CHECK_REFERRAL_REWARD_ISSUED, DATABASE_URL, REFERRAL_BONUS_PERCENTAGES
from logger import logger
+1
View File
@@ -1,5 +1,6 @@
from aiogram.filters import BaseFilter
from aiogram.types import Message
from config import ADMIN_ID
-1
View File
@@ -14,7 +14,6 @@ from .payments import router as payments_router
from .profile import router as profile_router
from .start import router as start_router
router = Router(name="handlers_main_router")
router.include_routers(
@@ -5,7 +5,6 @@ from backup import backup_database
from filters.admin import IsAdminFilter
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
router = Router()
-1
View File
@@ -8,7 +8,6 @@ from filters.admin import IsAdminFilter
from keyboard import build_bans_kb
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
router = Router()
+1 -1
View File
@@ -17,7 +17,7 @@ def build_clusters_editor_kb(servers: dict) -> InlineKeyboardMarkup:
cluster_names = list(servers.keys())
for i in range(0, len(cluster_names), 2):
row_buttons = []
for cluster_name in cluster_names[i:i+2]:
for cluster_name in cluster_names[i : i + 2]:
row_buttons.append(
InlineKeyboardButton(
text=f"⚙️ {cluster_name}",
+2 -3
View File
@@ -4,14 +4,13 @@ from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, Message
from config import USERNAME_BOT
from config import USERNAME_BOT
from database import create_coupon, delete_coupon, get_all_coupons
from filters.admin import IsAdminFilter
from keyboard import AdminCouponDeleteCallback, build_coupons_kb, build_coupons_list_kb
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
from logger import logger
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
router = Router()
@@ -6,7 +6,6 @@ from aiogram.types import CallbackQuery
from filters.admin import IsAdminFilter
from handlers.admin.panel.keyboard import AdminPanelCallback, build_admin_back_kb, build_restart_kb
router = Router()
+1 -2
View File
@@ -7,10 +7,9 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, Message
from filters.admin import IsAdminFilter
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
from keyboard import AdminSenderCallback, build_clusters_kb, build_sender_kb
from logger import logger
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
router = Router()
+1 -3
View File
@@ -2,17 +2,15 @@ from datetime import datetime
from typing import Any
import pytz
from aiogram import F, Router
from aiogram.exceptions import TelegramBadRequest
from aiogram.types import CallbackQuery
from filters.admin import IsAdminFilter
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
from keyboard import build_stats_kb
from logger import logger
from utils.csv_export import export_payments_csv, export_users_csv
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb
router = Router()
+1 -1
View File
@@ -3,8 +3,8 @@ from datetime import datetime, timezone
from aiogram.filters.callback_data import CallbackData
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import RENEWAL_PRICES
from config import RENEWAL_PRICES
from ..panel.keyboard import build_admin_back_btn
+4 -7
View File
@@ -1,19 +1,16 @@
import asyncio
from datetime import datetime, timedelta, timezone
from typing import Any
import pytz
from aiogram import F, Router, types
from aiogram.exceptions import TelegramBadRequest
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import TOTAL_GB
from utils.csv_export import export_referrals_csv
from config import TOTAL_GB
from database import (
delete_key,
delete_user_data,
@@ -27,8 +24,10 @@ from database import (
from filters.admin import IsAdminFilter
from handlers.keys.key_utils import delete_key_from_cluster, get_user_traffic, renew_key_in_cluster, update_subscription
from handlers.utils import sanitize_key_name
from logger import logger
from utils.csv_export import export_referrals_csv
from ..panel.keyboard import AdminPanelCallback, build_admin_back_kb, build_admin_back_btn
from keyboards.admin.users_kb import (
from ..users.keyboard import (
AdminUserEditorCallback,
AdminUserKeyEditorCallback,
build_editor_kb,
@@ -42,8 +41,6 @@ from keyboards.admin.users_kb import (
build_users_key_expiry_kb,
build_users_key_show_kb,
)
from logger import logger
MOSCOW_TZ = pytz.timezone("Europe/Moscow")
+1 -3
View File
@@ -1,19 +1,17 @@
import random
import secrets
from typing import Any
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import CAPTCHA_EMOJIS
from handlers.texts import CAPTCHA_PROMPT_MSG
from logger import logger
from .utils import edit_or_send_message
router = Router()
+1 -2
View File
@@ -3,10 +3,9 @@ from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import CallbackQuery, InlineKeyboardButton, LabeledPrice, Message, PreCheckoutQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import RUB_TO_XTR
from logger import logger
from .utils import edit_or_send_message
-1
View File
@@ -4,7 +4,6 @@ from aiogram import Router
from .instructions import router as instructions_router
router = Router(name="instructions_main_router")
router.include_routers(
+2 -4
View File
@@ -1,16 +1,15 @@
import os
from typing import Any
from aiogram import F, Router, types
from aiogram import F, Router
from aiogram.types import (
CallbackQuery,
InlineKeyboardButton,
Message,
)
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import CONNECT_MACOS, CONNECT_WINDOWS, SUPPORT_CHAT_URL
from config import CONNECT_MACOS, CONNECT_WINDOWS, SUPPORT_CHAT_URL
from database import get_key_details
from handlers.texts import (
CONNECT_TV_TEXT,
@@ -21,7 +20,6 @@ from handlers.texts import (
)
from handlers.utils import edit_or_send_message
router = Router()
-1
View File
@@ -5,7 +5,6 @@ from aiogram import Router
from .key_management import router as management_router
from .keys import router as keys_router
router = Router(name="keys_main_router")
router.include_routers(
+5 -8
View File
@@ -1,15 +1,18 @@
import asyncio
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.types import CallbackQuery, InlineKeyboardButton, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from handlers.payments.yookassa_pay import process_custom_amount_input
from py3xui import AsyncApi
from bot import bot
from client import delete_client
from config import (
ADMIN_PASSWORD,
ADMIN_USERNAME,
@@ -27,10 +30,6 @@ from config import (
USE_COUNTRY_SELECTION,
USE_NEW_PAYMENT_FLOW,
)
from py3xui import AsyncApi
from bot import bot
from client import delete_client
from database import (
add_connection,
check_connection_exists,
@@ -52,7 +51,6 @@ from handlers.buttons.add_subscribe import (
)
from handlers.keys.key_utils import create_client_on_server, create_key_on_cluster
from handlers.payments.robokassa_pay import handle_custom_amount_input
from handlers.payments.yookassa_pay import process_custom_amount_input
from handlers.texts import (
DISCOUNTS,
key_message_success,
@@ -64,7 +62,6 @@ from handlers.texts import (
from handlers.utils import edit_or_send_message, generate_random_email, get_least_loaded_cluster
from logger import logger
router = Router()
moscow_tz = pytz.timezone("Europe/Moscow")
+2 -3
View File
@@ -1,12 +1,11 @@
import asyncio
from typing import Any
from config import ADMIN_PASSWORD, ADMIN_USERNAME, LIMIT_IP, PUBLIC_LINK, SUPERNODE, TOTAL_GB, DATABASE_URL
from py3xui import AsyncApi
import asyncpg
from py3xui import AsyncApi
from client import ClientConfig, add_client, delete_client, extend_client_key, get_client_traffic, toggle_client
from config import ADMIN_PASSWORD, ADMIN_USERNAME, LIMIT_IP, PUBLIC_LINK, SUPERNODE, TOTAL_GB, DATABASE_URL
from database import get_servers, store_key
from handlers.utils import get_least_loaded_cluster
from logger import logger
+6 -13
View File
@@ -2,16 +2,17 @@ import asyncio
import locale
import os
import time
from datetime import datetime, timedelta
from typing import Any
import asyncpg
import pytz
from aiogram import F, Router, types
from aiogram.types import CallbackQuery, InlineKeyboardButton, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from handlers.payments.yookassa_pay import process_custom_amount_input
from bot import bot
from config import (
CONNECT_ANDROID,
CONNECT_IOS,
@@ -28,8 +29,6 @@ from config import (
USE_NEW_PAYMENT_FLOW,
TOGGLE_CLIENT,
)
from bot import bot
from database import (
check_server_name_by_cluster,
create_temporary_data,
@@ -57,7 +56,6 @@ from handlers.keys.key_utils import (
toggle_client_on_cluster,
)
from handlers.payments.robokassa_pay import handle_custom_amount_input
from handlers.payments.yookassa_pay import process_custom_amount_input
from handlers.texts import (
DISCOUNTS,
KEY_NOT_FOUND_MSG,
@@ -78,7 +76,6 @@ from handlers.texts import (
from handlers.utils import edit_or_send_message, handle_error
from logger import logger
locale.setlocale(locale.LC_TIME, "ru_RU.UTF-8")
router = Router()
@@ -354,7 +351,7 @@ async def process_callback_unfreeze_subscription_confirm(callback_query: Callbac
email=email,
client_id=client_id,
new_expiry_time=new_expiry_time,
total_gb=TOTAL_GB
total_gb=TOTAL_GB,
)
text_ok = SUBSCRIPTION_UNFROZEN_MSG
builder = InlineKeyboardBuilder()
@@ -549,14 +546,10 @@ async def process_callback_delete_key(callback_query: CallbackQuery):
if callback_query.message.caption:
await callback_query.message.edit_caption(
caption=DELETE_KEY_CONFIRM_MSG,
reply_markup=confirmation_keyboard
caption=DELETE_KEY_CONFIRM_MSG, reply_markup=confirmation_keyboard
)
else:
await callback_query.message.edit_text(
text=DELETE_KEY_CONFIRM_MSG,
reply_markup=confirmation_keyboard
)
await callback_query.message.edit_text(text=DELETE_KEY_CONFIRM_MSG, reply_markup=confirmation_keyboard)
except Exception as e:
logger.error(f"Ошибка при обработке запроса на удаление ключа {client_id}: {e}")
+1 -4
View File
@@ -4,18 +4,16 @@ import random
import re
import time
import urllib.parse
from datetime import datetime
import aiohttp
import asyncpg
import pytz
from aiohttp import web
from config import (
DATABASE_URL,
PROJECT_NAME,
SUB_MESSAGE,
SUPERNODE,
SUPPORT_CHAT_URL,
TOTAL_GB,
@@ -23,7 +21,6 @@ from config import (
USERNAME_BOT,
USE_COUNTRY_SELECTION,
)
from database import get_key_details, get_servers
from handlers.utils import convert_to_bytes
from logger import logger
-1
View File
@@ -5,7 +5,6 @@ from aiogram import Router
from .general_notifications import router as general_notifications_router
from .special_notifications import router as special_notifications_router
router = Router(name="notifications_main_router")
router.include_routers(general_notifications_router, special_notifications_router)
@@ -1,9 +1,10 @@
import asyncio
from datetime import datetime, timedelta
import asyncpg
import pytz
from aiogram import Bot, Router
from config import (
DATABASE_URL,
NOTIFICATION_TIME,
@@ -48,6 +49,7 @@ router = Router()
moscow_tz = pytz.timezone("Europe/Moscow")
async def periodic_notifications(bot: Bot):
"""
Обработчик, который:
@@ -98,6 +100,7 @@ async def periodic_notifications(bot: Bot):
await asyncio.sleep(NOTIFICATION_TIME)
async def notify_24h_keys(bot: Bot, conn: asyncpg.Connection, current_time: int, threshold_time_24h: int, keys: list):
logger.info("Начало проверки подписок, истекающих через 24 часа.")
@@ -149,6 +152,7 @@ async def notify_24h_keys(bot: Bot, conn: asyncpg.Connection, current_time: int,
logger.info("✅ Обработка всех уведомлений за 24 часа завершена.")
await asyncio.sleep(1)
async def notify_10h_keys(bot: Bot, conn: asyncpg.Connection, current_time: int, threshold_time_10h: int, keys: list):
"""
Отправляет уведомления пользователям о том, что их подписка истекает через 10 часов.
@@ -208,6 +212,7 @@ async def notify_10h_keys(bot: Bot, conn: asyncpg.Connection, current_time: int,
logger.info("✅ Обработка всех уведомлений за 10 часов завершена.")
await asyncio.sleep(1)
async def handle_expired_keys(bot: Bot, conn: asyncpg.Connection, current_time: int, keys: list):
"""
Обрабатывает истекшие ключи, проверяя продление или удаление.
@@ -319,6 +324,7 @@ async def handle_expired_keys(bot: Bot, conn: asyncpg.Connection, current_time:
logger.info("✅ Обработка истекших ключей завершена.")
await asyncio.sleep(1)
async def process_auto_renew_or_notify(
bot, conn, key: dict, notification_id: str, renewal_period_months: int, standard_photo: str, standard_caption: str
):
-1
View File
@@ -1,7 +1,6 @@
import os
import aiofiles
from aiogram import Bot
from aiogram.exceptions import TelegramForbiddenError
from aiogram.types import BufferedInputFile, InlineKeyboardMarkup
@@ -1,25 +1,22 @@
import asyncio
from datetime import datetime, timedelta
import asyncpg
import pytz
from aiogram import Bot, Router, types
from aiogram.exceptions import TelegramForbiddenError
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import NOTIFY_EXTRA_DAYS, NOTIFY_INACTIVE, NOTIFY_INACTIVE_TRAFFIC, SUPPORT_CHAT_URL, TRIAL_TIME
from config import NOTIFY_EXTRA_DAYS, NOTIFY_INACTIVE, NOTIFY_INACTIVE_TRAFFIC, SUPPORT_CHAT_URL, TRIAL_TIME
from database import (
add_notification,
check_notification_time,
create_blocked_user,
)
from handlers.texts import TRIAL_INACTIVE_FIRST_MSG, TRIAL_INACTIVE_BONUS_MSG, ZERO_TRAFFIC_MSG
from handlers.keys.key_utils import get_user_traffic
from handlers.texts import TRIAL_INACTIVE_FIRST_MSG, TRIAL_INACTIVE_BONUS_MSG, ZERO_TRAFFIC_MSG
from logger import logger
router = Router()
moscow_tz = pytz.timezone("Europe/Moscow")
@@ -84,16 +81,11 @@ async def notify_inactive_trial_users(bot: Bot, conn: asyncpg.Connection):
if trial_extended:
total_days = NOTIFY_EXTRA_DAYS + TRIAL_TIME
message = TRIAL_INACTIVE_BONUS_MSG.format(
display_name=display_name,
NOTIFY_EXTRA_DAYS=NOTIFY_EXTRA_DAYS,
total_days=total_days
display_name=display_name, NOTIFY_EXTRA_DAYS=NOTIFY_EXTRA_DAYS, total_days=total_days
)
await conn.execute("UPDATE connections SET trial = -1 WHERE tg_id = $1", tg_id)
else:
message = TRIAL_INACTIVE_FIRST_MSG.format(
display_name=display_name,
TRIAL_TIME=TRIAL_TIME
)
message = TRIAL_INACTIVE_FIRST_MSG.format(display_name=display_name, TRIAL_TIME=TRIAL_TIME)
try:
await bot.send_message(tg_id, message, reply_markup=keyboard)
+1 -1
View File
@@ -1,6 +1,7 @@
from aiogram import F, Router
from aiogram.types import CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import (
CRYPTO_BOT_ENABLE,
DONATIONS_ENABLE,
@@ -12,7 +13,6 @@ from config import (
from handlers.texts import PAYMENT_METHODS_MSG
from .utils import edit_or_send_message
router = Router()
+1 -1
View File
@@ -1,6 +1,7 @@
__all__ = ("router",)
from aiogram import Router
from config import (
CRYPTO_BOT_ENABLE,
ROBOKASSA_ENABLE,
@@ -8,7 +9,6 @@ from config import (
YOOKASSA_ENABLE,
YOOMONEY_ENABLE,
)
from .cryprobot_pay import router as cryprobot_router
from .gift import router as gift_router
from .robokassa_pay import router as robokassa_router
+3 -3
View File
@@ -8,6 +8,9 @@ from aiogram.fsm.state import State, StatesGroup
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiohttp import web
from handlers.payments.utils import send_payment_success_notification
from robokassa import HashAlgorithm, Robokassa
from config import (
DATABASE_URL,
ROBOKASSA_ENABLE,
@@ -16,8 +19,6 @@ from config import (
ROBOKASSA_PASSWORD2,
ROBOKASSA_TEST_MODE,
)
from robokassa import HashAlgorithm, Robokassa
from database import (
add_connection,
add_payment,
@@ -26,7 +27,6 @@ from database import (
get_temporary_data,
update_balance,
)
from handlers.payments.utils import send_payment_success_notification
from handlers.texts import PAYMENT_OPTIONS
from handlers.utils import edit_or_send_message
from logger import logger
+3 -6
View File
@@ -1,10 +1,8 @@
import html
import os
from typing import Any
import asyncpg
from aiogram import F, Router
from aiogram.enums import ParseMode
from aiogram.fsm.context import FSMContext
@@ -17,6 +15,7 @@ from aiogram.types import (
Message,
)
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import (
DATABASE_URL,
INLINE_MODE,
@@ -27,7 +26,6 @@ from config import (
TRIAL_TIME,
USERNAME_BOT,
)
from database import get_balance, get_key_count, get_last_payments, get_referral_stats, get_trial
from handlers.buttons.profile import (
ADD_SUB,
@@ -40,12 +38,11 @@ from handlers.buttons.profile import (
MY_SUBS,
PAYMENT,
)
from keyboards.admin.panel_kb import AdminPanelCallback
from logger import logger
from .admin.panel.keyboard import AdminPanelCallback
from .texts import profile_message_send, invite_message_send, get_referral_link
from .utils import edit_or_send_message
router = Router()
+4 -7
View File
@@ -10,6 +10,8 @@ from aiogram.types import (
Message,
)
from aiogram.utils.keyboard import InlineKeyboardBuilder
from bot import bot
from config import (
CAPTCHA_ENABLE,
CHANNEL_EXISTS,
@@ -19,8 +21,6 @@ from config import (
DONATIONS_ENABLE,
SUPPORT_CHAT_URL,
)
from bot import bot
from database import (
add_connection,
add_referral,
@@ -43,12 +43,10 @@ from handlers.texts import (
NEW_REFERRAL_NOTIFICATION,
COUPON_SUCCESS_MSG,
)
from keyboards.admin.panel_kb import AdminPanelCallback
from logger import logger
from .admin.panel.keyboard import AdminPanelCallback
from .utils import edit_or_send_message
router = Router()
@@ -274,8 +272,7 @@ async def process_start_logic(
await message.answer(REFERRAL_SUCCESS_MSG.format(referrer_tg_id=referrer_tg_id))
try:
await bot.send_message(
referrer_tg_id,
NEW_REFERRAL_NOTIFICATION.format(referred_id=message.chat.id)
referrer_tg_id, NEW_REFERRAL_NOTIFICATION.format(referred_id=message.chat.id)
)
logger.info(
f"Уведомление отправлено пользователю {referrer_tg_id} о новом реферале {message.chat.id}"
+1 -2
View File
@@ -7,11 +7,10 @@ import string
import aiofiles
import aiohttp
import asyncpg
from aiogram.types import BufferedInputFile, InlineKeyboardMarkup, InputMediaPhoto, Message
from config import DATABASE_URL
from bot import bot
from config import DATABASE_URL
from database import get_all_keys, get_servers
from logger import logger
-2
View File
@@ -1,12 +1,10 @@
import logging
import os
import sys
from datetime import timedelta
from loguru import logger
log_folder = "logs"
if not os.path.exists(log_folder):
-1
View File
@@ -1,5 +1,4 @@
from collections.abc import Iterable
from typing import Any, Optional, Type, Union
from aiogram import Dispatcher
from aiogram.dispatcher.middlewares.base import BaseMiddleware
+1
View File
@@ -3,6 +3,7 @@ from typing import Any
from aiogram import BaseMiddleware
from aiogram.types import CallbackQuery, Message, TelegramObject
from config import ADMIN_ID
+1 -1
View File
@@ -2,9 +2,9 @@ from collections.abc import Awaitable, Callable
from typing import Any
import asyncpg
from aiogram import BaseMiddleware
from aiogram.types import TelegramObject
from config import DATABASE_URL
+3 -5
View File
@@ -1,19 +1,17 @@
import asyncio
import re
from datetime import datetime, timedelta
from aiogram.types import InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import ADMIN_ID, PING_TIME
from ping3 import ping
from bot import bot
from config import ADMIN_ID, PING_TIME
from database import get_servers
from keyboards.admin.servers_kb import AdminServerEditorCallback
from handlers.admin.servers.keyboard import AdminServerCallback
from logger import logger
last_ping_times = {}
last_down_times = {}
notified_servers = set()
@@ -49,7 +47,7 @@ async def notify_admin(server_name: str, status: str, down_duration: timedelta =
builder.row(
InlineKeyboardButton(
text="Управление сервером",
callback_data=AdminServerEditorCallback(action="servers_manage", data=server_name).pack(),
callback_data=AdminServerCallback(action="manage", data=server_name).pack(),
)
)
+1 -1
View File
@@ -1,6 +1,6 @@
import csv
from io import StringIO
from typing import Any
import csv
from aiogram.types import BufferedInputFile