Refactor file handling to use aiofiles for asynchronous operations

- Replaced synchronous file reading with asynchronous file handling using aiofiles in multiple handlers and the backup module.
- Improved performance and responsiveness when sending images and backups by utilizing async file operations.
- Ensured consistent use of BufferedInputFile across all relevant functions for better code maintainability.
This commit is contained in:
Zakhar Izmaylov
2025-01-21 12:03:56 +03:00
parent a2c71a49f2
commit 44cadc29ba
5 changed files with 30 additions and 21 deletions
+4 -3
View File
@@ -1,7 +1,7 @@
import os
import subprocess
from datetime import datetime
import aiofiles
from aiogram.types import BufferedInputFile
from config import ADMIN_ID, BACK_DIR, DB_NAME, DB_PASSWORD, DB_USER, PG_HOST, PG_PORT
@@ -58,8 +58,9 @@ def _create_database_backup():
async def _send_backup_to_admin(bot, backup_file_path):
try:
with open(backup_file_path, "rb") as backup_file:
backup_input_file = BufferedInputFile(backup_file.read(), filename=os.path.basename(backup_file_path))
async with aiofiles.open(backup_file_path, "rb") as backup_file:
backup_file_data = await backup_file.read()
backup_input_file = BufferedInputFile(backup_file_data, filename=os.path.basename(backup_file_path))
admin_ids: int | list[int] = ADMIN_ID
if isinstance(admin_ids, list):
for id in admin_ids:
+4 -3
View File
@@ -1,6 +1,6 @@
import os
from typing import Any
import aiofiles
import asyncpg
from aiogram import F, Router, types
from aiogram.types import BufferedInputFile, InlineKeyboardButton
@@ -45,9 +45,10 @@ async def send_instructions(
else:
send_photo = callback_query_or_message.answer_photo
with open(image_path, "rb") as image_from_buffer:
async with aiofiles.open(image_path, "rb") as image_from_buffer:
image_data = await image_from_buffer.read()
await send_photo(
BufferedInputFile(image_from_buffer.read(), filename="instructions.jpg"),
BufferedInputFile(image_data, filename="instructions.jpg"),
caption=instructions_message,
reply_markup=builder.as_markup(),
)
+7 -5
View File
@@ -3,7 +3,7 @@ import locale
import os
from datetime import datetime, timedelta
from typing import Any
import aiofiles
from aiogram import F, Router, types
from aiogram.types import BufferedInputFile, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
@@ -123,9 +123,10 @@ async def send_with_optional_image(send_message, send_photo, image_path, text, k
Отправляет сообщение с изображением, если файл существует. В противном случае отправляет только текст.
"""
if os.path.isfile(image_path):
with open(image_path, "rb") as image_file:
async with aiofiles.open(image_path, "rb") as image_file:
image_data = await image_file.read()
await send_photo(
photo=BufferedInputFile(image_file.read(), filename=os.path.basename(image_path)),
photo=BufferedInputFile(image_data, filename=os.path.basename(image_path)),
caption=text,
reply_markup=keyboard,
)
@@ -219,9 +220,10 @@ async def process_callback_view_key(callback_query: types.CallbackQuery, session
await callback_query.message.answer("Файл изображения не найден.")
return
with open(image_path, "rb") as image_file:
async with aiofiles.open(image_path, "rb") as image_file:
image_data = await image_file.read()
await callback_query.message.answer_photo(
photo=BufferedInputFile(image_file.read(), filename="pic_view.jpg"),
photo=BufferedInputFile(image_data, filename="pic_view.jpg"),
caption=response_message,
reply_markup=keyboard,
)
+11 -7
View File
@@ -3,6 +3,7 @@ from typing import Any
import asyncpg
from aiogram import F, Router, types
import aiofiles
from aiogram.fsm.context import FSMContext
from aiogram.types import BufferedInputFile, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
@@ -83,16 +84,17 @@ async def process_callback_view_profile(
builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="start"))
if os.path.isfile(image_path):
with open(image_path, "rb") as image_file:
async with aiofiles.open(image_path, "rb") as image_file:
image_data = await image_file.read()
if is_callback:
await callback_query_or_message.message.answer_photo(
photo=BufferedInputFile(image_file.read(), filename="pic.jpg"),
photo=BufferedInputFile(image_data, filename="pic.jpg"),
caption=profile_message,
reply_markup=builder.as_markup(),
)
else:
await callback_query_or_message.answer_photo(
photo=BufferedInputFile(image_file.read(), filename="pic.jpg"),
photo=BufferedInputFile(image_data, filename="pic.jpg"),
caption=profile_message,
reply_markup=builder.as_markup(),
)
@@ -173,9 +175,10 @@ async def view_tariffs_handler(callback_query: types.CallbackQuery):
)
if os.path.isfile(image_path):
with open(image_path, "rb") as image_file:
async with aiofiles.open(image_path, "rb") as image_file:
image_data = await image_file.read()
await callback_query.message.answer_photo(
photo=BufferedInputFile(image_file.read(), filename="tariffs.jpg"),
photo=BufferedInputFile(image_data, filename="tariffs.jpg"),
caption=tariffs_message,
reply_markup=builder.as_markup(),
)
@@ -200,9 +203,10 @@ async def invite_handler(callback_query: types.CallbackQuery):
builder = InlineKeyboardBuilder()
builder.row(InlineKeyboardButton(text="👤 Личный кабинет", callback_data="profile"))
if os.path.isfile(image_path):
with open(image_path, "rb") as image_file:
async with aiofiles.open(image_path, "rb") as image_file:
image_data = await image_file.read()
await callback_query.message.answer_photo(
photo=BufferedInputFile(image_file.read(), filename="pic_invite.jpg"),
photo=BufferedInputFile(image_data, filename="pic_invite.jpg"),
caption=invite_message,
reply_markup=builder.as_markup(),
)
+4 -3
View File
@@ -1,6 +1,6 @@
import os
from typing import Any
import aiofiles
from aiogram import F, Router
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
@@ -190,9 +190,10 @@ async def show_start_menu(message: Message, admin: bool, session: Any):
builder.row(InlineKeyboardButton(text="🌐 О VPN", callback_data="about_vpn"))
if os.path.isfile(image_path):
with open(image_path, "rb") as image_from_buffer:
async with aiofiles.open(image_path, "rb") as image_from_buffer:
image_data = await image_from_buffer.read()
await message.answer_photo(
photo=BufferedInputFile(image_from_buffer.read(), filename="pic.jpg"),
photo=BufferedInputFile(image_data, filename="pic.jpg"),
caption=WELCOME_TEXT,
reply_markup=builder.as_markup(),
)