ruff format/ minor fixes and improvements

This commit is contained in:
Vladless
2025-10-24 09:39:54 +03:00
parent a573fdc4d4
commit 3c25fb3015
24 changed files with 183 additions and 124 deletions
View File
Binary file not shown.
Binary file not shown.
+9 -23
View File
@@ -1,6 +1,6 @@
from datetime import datetime
from sqlalchemy import delete, exists, or_, select, update, func
from sqlalchemy import delete, exists, func, or_, select, update
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession
@@ -11,12 +11,12 @@ from database.models import (
CouponUsage,
Gift,
GiftUsage,
Key,
Notification,
Payment,
Referral,
TemporaryData,
User,
Key,
)
from logger import logger
@@ -81,17 +81,13 @@ async def check_user_exists(session: AsyncSession, tg_id: int) -> bool:
async def get_balance(session: AsyncSession, tg_id: int) -> float:
result = await session.execute(
select(func.coalesce(User.balance, 0.0)).where(User.tg_id == tg_id)
)
result = await session.execute(select(func.coalesce(User.balance, 0.0)).where(User.tg_id == tg_id))
return round(float(result.scalar_one()), 1)
async def set_user_balance(session: AsyncSession, tg_id: int, balance: float) -> None:
try:
await session.execute(
update(User).where(User.tg_id == tg_id).values(balance=balance)
)
await session.execute(update(User).where(User.tg_id == tg_id).values(balance=balance))
await session.commit()
except SQLAlchemyError as e:
logger.error(f"Ошибка при установке баланса для пользователя {tg_id}: {e}")
@@ -100,9 +96,7 @@ async def set_user_balance(session: AsyncSession, tg_id: int, balance: float) ->
async def update_trial(session: AsyncSession, tg_id: int, status: int):
try:
await session.execute(
update(User).where(User.tg_id == tg_id).values(trial=status)
)
await session.execute(update(User).where(User.tg_id == tg_id).values(trial=status))
await session.commit()
logger.info(f"[DB] Триал статус обновлён для пользователя {tg_id}: {status}")
except SQLAlchemyError as e:
@@ -111,9 +105,7 @@ async def update_trial(session: AsyncSession, tg_id: int, status: int):
async def get_trial(session: AsyncSession, tg_id: int) -> int:
result = await session.execute(
select(func.coalesce(User.trial, 0)).where(User.tg_id == tg_id)
)
result = await session.execute(select(func.coalesce(User.trial, 0)).where(User.tg_id == tg_id))
return int(result.scalar_one())
@@ -189,19 +181,13 @@ async def delete_user_data(session: AsyncSession, tg_id: int):
try:
await session.execute(delete(Notification).where(Notification.tg_id == tg_id))
await session.execute(
delete(GiftUsage).where(
GiftUsage.gift_id.in_(select(Gift.gift_id).where(Gift.sender_tg_id == tg_id))
)
delete(GiftUsage).where(GiftUsage.gift_id.in_(select(Gift.gift_id).where(Gift.sender_tg_id == tg_id)))
)
await session.execute(delete(Gift).where(Gift.sender_tg_id == tg_id))
await session.execute(
update(Gift).where(Gift.recipient_tg_id == tg_id).values(recipient_tg_id=None)
)
await session.execute(update(Gift).where(Gift.recipient_tg_id == tg_id).values(recipient_tg_id=None))
await session.execute(delete(Payment).where(Payment.tg_id == tg_id))
await session.execute(
delete(Referral).where(
or_(Referral.referrer_tg_id == tg_id, Referral.referred_tg_id == tg_id)
)
delete(Referral).where(or_(Referral.referrer_tg_id == tg_id, Referral.referred_tg_id == tg_id))
)
await session.execute(delete(CouponUsage).where(CouponUsage.user_id == tg_id))
await delete_key(session, tg_id)
+5 -3
View File
@@ -537,7 +537,7 @@ async def handle_sync_server(
expire_iso = (
datetime.utcfromtimestamp(key["expiry_time"] / 1000).replace(tzinfo=timezone.utc).isoformat()
)
remna = RemnawaveAPI(key["api_url"])
if not await remna.login(REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD):
logger.error(f"Не удалось авторизоваться в Remnawave для сервера {server_name}")
@@ -561,7 +561,7 @@ async def handle_sync_server(
traffic_limit_bytes=traffic_limit_bytes,
hwid_device_limit=hwid_limit,
)
if not success:
logger.warning("[Sync] ошибка обновления, пробуем пересоздать")
@@ -673,7 +673,9 @@ async def handle_sync_cluster(
filtered_servers = cluster_servers
if subgroup_title:
filtered_servers = [s for s in cluster_servers if subgroup_title in s.get("tariff_subgroups", [])]
filtered_servers = [
s for s in cluster_servers if subgroup_title in s.get("tariff_subgroups", [])
]
if not filtered_servers:
logger.warning(
f"[Sync] В кластере {cluster_name} не найдено серверов для подгруппы '{subgroup_title}'. Использую весь кластер."
+3 -1
View File
@@ -23,7 +23,9 @@ async def build_panel_kb(admin_role: str) -> InlineKeyboardMarkup:
builder = InlineKeyboardBuilder()
builder.row(
InlineKeyboardButton(text="👤 Поиск пользователя", callback_data=AdminPanelCallback(action="search_user").pack()),
InlineKeyboardButton(
text="👤 Поиск пользователя", callback_data=AdminPanelCallback(action="search_user").pack()
),
InlineKeyboardButton(text="🔑 Поиск подписок", callback_data=AdminPanelCallback(action="search_key").pack()),
)
+7 -7
View File
@@ -137,14 +137,14 @@ async def process_callback_delete_server(
builder = InlineKeyboardBuilder()
for s_name, key_count in all_servers:
callback_data = f"transfer_to_server|{s_name}|{server_name}"
if len(callback_data.encode('utf-8')) > 64:
if len(callback_data.encode("utf-8")) > 64:
await callback_query.message.edit_text(
text=f"❌ Ошибка: название сервера '{s_name}' слишком длинное.\n\n"
f"Пожалуйста, переименуйте сервер в более короткое название и попробуйте снова.",
f"Пожалуйста, переименуйте сервер в более короткое название и попробуйте снова.",
reply_markup=build_admin_back_kb("clusters"),
)
return
builder.row(
InlineKeyboardButton(
text=f"{s_name} ({key_count})",
@@ -199,14 +199,14 @@ async def process_callback_delete_server(
builder = InlineKeyboardBuilder()
for cl_name, key_count in all_clusters:
callback_data = f"transfer_to_cluster|{cl_name}|{cluster_name}|{server_name}"
if len(callback_data.encode('utf-8')) > 64:
if len(callback_data.encode("utf-8")) > 64:
await callback_query.message.edit_text(
text=f"❌ Ошибка: название сервера '{server_name}' или кластера '{cl_name}' слишком длинное.\n\n"
f"Пожалуйста, переименуйте сервер в более короткое название и попробуйте снова.",
f"Пожалуйста, переименуйте сервер в более короткое название и попробуйте снова.",
reply_markup=build_admin_back_kb("clusters"),
)
return
builder.row(
InlineKeyboardButton(
text=f"{cl_name} ({key_count})",
@@ -448,7 +448,7 @@ async def apply_field_edit(message: types.Message, state: FSMContext, session: A
reply_markup=build_admin_back_kb("clusters"),
)
return
success = await update_server_name_with_keys(session, server_name, value)
if success:
server_name = value
+3 -2
View File
@@ -1226,7 +1226,9 @@ async def change_expiry_time(expiry_time: int, email: str, session: AsyncSession
key_subgroup = None
if tariff_id:
result = await session.execute(
select(Tariff.traffic_limit, Tariff.device_limit, Tariff.subgroup_title).where(Tariff.id == tariff_id, Tariff.is_active.is_(True))
select(Tariff.traffic_limit, Tariff.device_limit, Tariff.subgroup_title).where(
Tariff.id == tariff_id, Tariff.is_active.is_(True)
)
)
tariff = result.first()
if tariff:
@@ -1234,7 +1236,6 @@ async def change_expiry_time(expiry_time: int, email: str, session: AsyncSession
device_limit = int(tariff[1]) if tariff[1] is not None else 0
key_subgroup = tariff[2]
servers = await get_servers(session=session)
if server_id in servers:
+1 -1
View File
@@ -227,7 +227,7 @@ async def handle_key_extension(
key_subgroup = None
if tariff:
key_subgroup = tariff.get('subgroup_title')
key_subgroup = tariff.get("subgroup_title")
await renew_key_in_cluster(
cluster_id=key.server_id,
+26 -10
View File
@@ -38,7 +38,17 @@ from database import (
update_trial,
)
from database.models import Key, Server, Tariff
from handlers.buttons import BACK, CONNECT_DEVICE, CONNECT_PHONE, MAIN_MENU, MY_SUB, PC_BUTTON, SUPPORT, TV_BUTTON, ROUTER_BUTTON
from handlers.buttons import (
BACK,
CONNECT_DEVICE,
CONNECT_PHONE,
MAIN_MENU,
MY_SUB,
PC_BUTTON,
ROUTER_BUTTON,
SUPPORT,
TV_BUTTON,
)
from handlers.keys.operations import create_client_on_server
from handlers.keys.operations.aggregated_links import make_aggregated_link
from handlers.texts import SELECT_COUNTRY_MSG, key_message_success
@@ -509,14 +519,16 @@ async def finalize_key_creation(
)
subgroup_code = tariff.subgroup_title if tariff and tariff.subgroup_title else None
cluster_all = [{
"server_name": server_info.server_name,
"api_url": server_info.api_url,
"panel_type": server_info.panel_type,
"inbound_id": getattr(server_info, "inbound_id", None),
"enabled": True,
"max_keys": getattr(server_info, "max_keys", None),
}]
cluster_all = [
{
"server_name": server_info.server_name,
"api_url": server_info.api_url,
"panel_type": server_info.panel_type,
"inbound_id": getattr(server_info, "inbound_id", None),
"enabled": True,
"max_keys": getattr(server_info, "max_keys", None),
}
]
link_to_show = await make_aggregated_link(
session=session,
@@ -575,7 +587,11 @@ async def finalize_key_creation(
is_full_remnawave = await is_full_remnawave_cluster(cluster_name, session)
is_vless = bool(public_link and public_link.lower().startswith("vless://")) or bool(need_vless_key)
final_link = public_link or remnawave_link
webapp_url = final_link if isinstance(final_link, str) and final_link.strip().lower().startswith(("http://", "https://")) else None
webapp_url = (
final_link
if isinstance(final_link, str) and final_link.strip().lower().startswith(("http://", "https://"))
else None
)
if panel_type == "remnawave" or is_full_remnawave:
if is_vless:
+2 -5
View File
@@ -77,16 +77,13 @@ async def process_callback_renew_key(callback_query: CallbackQuery, state: FSMCo
try:
hook_commands = await run_hooks(
"process_callback_renew_key",
callback_query=callback_query,
state=state,
session=session
"process_callback_renew_key", callback_query=callback_query, state=state, session=session
)
if hook_commands:
kb = insert_hook_buttons(kb, hook_commands)
except Exception as e:
logger.warning(f"[RENEW] Ошибка при применении хуков: {e}")
await edit_or_send_message(
target_message=callback_query.message,
text=f"Продление доступно с {dt_msk}",
+2 -2
View File
@@ -134,7 +134,7 @@ async def build_keys_response(records, session):
formatted_date_full = "без срока действия"
is_vless = False
if hasattr(record, 'tariff_id') and record.tariff_id:
if hasattr(record, "tariff_id") and record.tariff_id:
try:
tariff = await get_tariff_by_id(session, record.tariff_id)
if tariff and tariff.get("vless"):
@@ -143,7 +143,7 @@ async def build_keys_response(records, session):
pass
icon = "📶" if is_vless else "🔑"
key_button = InlineKeyboardButton(text=f"{icon} {key_display}", callback_data=f"view_key|{email}")
rename_button = InlineKeyboardButton(text=ALIAS, callback_data=f"rename_key|{client_id}")
builder.row(key_button, rename_button)
+11 -4
View File
@@ -1,19 +1,24 @@
import asyncio
from datetime import datetime, timezone
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession
from config import PUBLIC_LINK, REMNAWAVE_LOGIN, REMNAWAVE_PASSWORD, SUPERNODE
from database import get_servers, store_key, filter_cluster_by_subgroup
from database import filter_cluster_by_subgroup, get_servers, store_key
from database.models import Key, Tariff
from handlers.utils import get_least_loaded_cluster
from logger import CLOGGER as logger, PANEL_REMNA, PANEL_XUI
from logger import (
CLOGGER as logger,
PANEL_REMNA,
PANEL_XUI,
)
from panels._3xui import ClientConfig, add_client, get_xui_instance
from panels.remnawave import RemnawaveAPI
from .deletion import delete_key_from_cluster
from .aggregated_links import make_aggregated_link
from .deletion import delete_key_from_cluster
async def update_key_on_cluster(
@@ -229,7 +234,9 @@ async def update_subscription(
if subgroup_code:
prefiltered = await filter_cluster_by_subgroup(session, cluster_servers, subgroup_code, new_cluster_id)
if not prefiltered:
logger.warning(f"[Update] Пересоздание пропущено: нет серверов под подгруппу {subgroup_code} в {new_cluster_id}.")
logger.warning(
f"[Update] Пересоздание пропущено: нет серверов под подгруппу {subgroup_code} в {new_cluster_id}."
)
return
cluster_servers = prefiltered
+1 -1
View File
@@ -203,7 +203,7 @@ def prepare_headers(
"announce": "base64:" + base64.b64encode(announce_str.encode("utf-8")).decode("utf-8"),
"profile-web-page-url": f"https://t.me/{USERNAME_BOT}",
"subscription-userinfo": subscription_userinfo,
#"routing": "happ://routing/onadd/...",
# "routing": "happ://routing/onadd/...",
}
elif "Hiddify" in user_agent:
parts = subscription_info.split(" - ")[0].split(": ")
@@ -536,7 +536,7 @@ async def process_auto_renew_or_notify(
keyboard = build_notification_kb(email)
await add_notification(conn, tg_id, notification_id)
text_to_send = message_text if 'message_text' in locals() else standard_caption
text_to_send = message_text if "message_text" in locals() else standard_caption
await send_notification(bot, tg_id, standard_photo, text_to_send, keyboard)
return
@@ -566,7 +566,7 @@ async def process_auto_renew_or_notify(
f"Продление подписки {email} на {duration_days} дней для пользователя {tg_id}. Баланс: {balance}, списываем: {renewal_cost}"
)
key_subgroup = selected_tariff.get('subgroup_title')
key_subgroup = selected_tariff.get("subgroup_title")
await renew_key_in_cluster(
cluster_id=server_id,
+7 -3
View File
@@ -1,4 +1,5 @@
import os
from typing import Any
from aiogram import F, Router
@@ -6,6 +7,7 @@ from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, InlineKeyboardButton, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from bot import bot
@@ -25,6 +27,7 @@ from database import (
get_user_snapshot,
upsert_source_if_empty,
)
from database.models import TrackingSource
from handlers.buttons import (
ABOUT_VPN,
BACK,
@@ -55,8 +58,7 @@ from logger import logger
from .admin.panel.keyboard import AdminPanelCallback
from .refferal import handle_referral_link
from .utils import edit_or_send_message, extract_user_data
from sqlalchemy import select
from database.models import TrackingSource
router = Router()
processing_gifts = set()
@@ -235,7 +237,9 @@ async def show_start_menu(
key_cnt = key_count or 0
show_trial = (trial_status in (-1, 0)) and (not TRIAL_TIME_DISABLE) and (key_cnt == 0)
show_profile = (key_cnt > 0) or (((not SHOW_START_MENU_ONCE) or (trial_status not in (-1, 0)) or TRIAL_TIME_DISABLE) and (not show_trial))
show_profile = (key_cnt > 0) or (
((not SHOW_START_MENU_ONCE) or (trial_status not in (-1, 0)) or TRIAL_TIME_DISABLE) and (not show_trial)
)
if show_trial:
kb.row(InlineKeyboardButton(text=TRIAL_SUB, callback_data="create_key"))
+92 -49
View File
@@ -1,3 +1,4 @@
import asyncio
import html
import os
import re
@@ -5,8 +6,6 @@ import secrets
import string
from collections import OrderedDict
import asyncio
from datetime import datetime, timedelta
import aiofiles
@@ -14,9 +13,9 @@ import aiofiles
from aiogram.types import (
BufferedInputFile,
InlineKeyboardMarkup,
InputMediaAnimation,
InputMediaPhoto,
InputMediaVideo,
InputMediaAnimation,
Message,
)
from sqlalchemy import func, select
@@ -201,20 +200,20 @@ def format_hours(hours: int) -> str:
def get_media_type(media_path: str) -> str:
if not media_path:
return 'photo'
return "photo"
ext = os.path.splitext(media_path.lower())[1]
if ext in ['.jpg', '.jpeg', '.png', '.webp']:
return 'photo'
if ext in [".jpg", ".jpeg", ".png", ".webp"]:
return "photo"
if ext in ['.mp4', '.mov', '.avi']:
return 'video'
if ext in [".mp4", ".mov", ".avi"]:
return "video"
if ext == '.gif':
return 'animation'
return 'photo'
if ext == ".gif":
return "animation"
return "photo"
async def edit_or_send_message(
@@ -227,8 +226,10 @@ async def edit_or_send_message(
disable_cache: bool = False,
):
if not hasattr(edit_or_send_message, "cache"):
from collections import OrderedDict
import asyncio
from collections import OrderedDict
edit_or_send_message.cache = OrderedDict()
edit_or_send_message.lock = asyncio.Lock()
edit_or_send_message.max = 256
@@ -236,49 +237,70 @@ async def edit_or_send_message(
def find_media_file(original_path: str) -> str | None:
if not original_path:
return None
if os.path.isfile(original_path):
return original_path
base_name = os.path.splitext(original_path)[0]
supported_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.mp4', '.mov', '.avi']
supported_extensions = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".mp4", ".mov", ".avi"]
for ext in supported_extensions:
fallback_path = base_name + ext
if os.path.isfile(fallback_path):
return fallback_path
return None
if media_path:
actual_media_path = find_media_file(media_path)
if actual_media_path:
media_type = get_media_type(actual_media_path)
cached_id = None
if not disable_cache:
async with edit_or_send_message.lock:
cached_id = edit_or_send_message.cache.get(actual_media_path)
if cached_id:
edit_or_send_message.cache.move_to_end(actual_media_path)
if cached_id:
try:
if media_type == 'photo':
await target_message.edit_media(InputMediaPhoto(media=cached_id, caption=text), reply_markup=reply_markup)
elif media_type == 'video':
await target_message.edit_media(InputMediaVideo(media=cached_id, caption=text), reply_markup=reply_markup)
elif media_type == 'animation':
await target_message.edit_media(InputMediaAnimation(media=cached_id, caption=text), reply_markup=reply_markup)
if media_type == "photo":
await target_message.edit_media(
InputMediaPhoto(media=cached_id, caption=text), reply_markup=reply_markup
)
elif media_type == "video":
await target_message.edit_media(
InputMediaVideo(media=cached_id, caption=text), reply_markup=reply_markup
)
elif media_type == "animation":
await target_message.edit_media(
InputMediaAnimation(media=cached_id, caption=text), reply_markup=reply_markup
)
return
except Exception:
try:
if media_type == 'photo':
await target_message.answer_photo(photo=cached_id, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
elif media_type == 'video':
await target_message.answer_video(video=cached_id, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
elif media_type == 'animation':
await target_message.answer_animation(animation=cached_id, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
if media_type == "photo":
await target_message.answer_photo(
photo=cached_id,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
elif media_type == "video":
await target_message.answer_video(
video=cached_id,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
elif media_type == "animation":
await target_message.answer_animation(
animation=cached_id,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
return
except Exception:
pass
@@ -286,30 +308,51 @@ async def edit_or_send_message(
async with aiofiles.open(actual_media_path, "rb") as f:
data = await f.read()
upload = BufferedInputFile(data, filename=os.path.basename(actual_media_path))
try:
if media_type == 'photo':
msg = await target_message.edit_media(InputMediaPhoto(media=upload, caption=text), reply_markup=reply_markup)
elif media_type == 'video':
msg = await target_message.edit_media(InputMediaVideo(media=upload, caption=text), reply_markup=reply_markup)
elif media_type == 'animation':
msg = await target_message.edit_media(InputMediaAnimation(media=upload, caption=text), reply_markup=reply_markup)
if media_type == "photo":
msg = await target_message.edit_media(
InputMediaPhoto(media=upload, caption=text), reply_markup=reply_markup
)
elif media_type == "video":
msg = await target_message.edit_media(
InputMediaVideo(media=upload, caption=text), reply_markup=reply_markup
)
elif media_type == "animation":
msg = await target_message.edit_media(
InputMediaAnimation(media=upload, caption=text), reply_markup=reply_markup
)
except Exception:
if media_type == 'photo':
msg = await target_message.answer_photo(photo=upload, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
elif media_type == 'video':
msg = await target_message.answer_video(video=upload, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
elif media_type == 'animation':
msg = await target_message.answer_animation(animation=upload, caption=text, reply_markup=reply_markup, disable_web_page_preview=disable_web_page_preview)
if media_type == "photo":
msg = await target_message.answer_photo(
photo=upload,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
elif media_type == "video":
msg = await target_message.answer_video(
video=upload,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
elif media_type == "animation":
msg = await target_message.answer_animation(
animation=upload,
caption=text,
reply_markup=reply_markup,
disable_web_page_preview=disable_web_page_preview,
)
file_id = None
if hasattr(msg, 'photo') and msg.photo:
if hasattr(msg, "photo") and msg.photo:
file_id = msg.photo[-1].file_id
elif hasattr(msg, 'video') and msg.video:
elif hasattr(msg, "video") and msg.video:
file_id = msg.video.file_id
elif hasattr(msg, 'animation') and msg.animation:
elif hasattr(msg, "animation") and msg.animation:
file_id = msg.animation.file_id
if file_id and not disable_cache:
async with edit_or_send_message.lock:
if actual_media_path not in edit_or_send_message.cache:
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -3
View File
@@ -3,17 +3,16 @@ from collections.abc import Iterable
from aiogram import Dispatcher
from aiogram.dispatcher.middlewares.base import BaseMiddleware
from config import DISABLE_DIRECT_START, CHANNEL_REQUIRED
from config import CHANNEL_REQUIRED, DISABLE_DIRECT_START
from middlewares.ban_checker import BanCheckerMiddleware
from middlewares.subscription import SubscriptionMiddleware
from .probe import StreamProbeMiddleware, MiddlewareProbe, TailHandlerProbe
from .admin import AdminMiddleware
from .answer import CallbackAnswerMiddleware
from .direct_start_blocker import DirectStartBlockerMiddleware
from .loggings import LoggingMiddleware
from .maintenance import MaintenanceModeMiddleware
from .probe import MiddlewareProbe, StreamProbeMiddleware, TailHandlerProbe
from .session import SessionMiddleware
from .throttling import ThrottlingMiddleware
from .user import UserMiddleware
+7 -5
View File
@@ -1,10 +1,12 @@
import time
from aiogram.dispatcher.middlewares.base import BaseMiddleware
from logger import logger
class StreamProbeMiddleware(BaseMiddleware):
def __init__(self, name: str = "global"):
def __init__(self, name: str = "global") -> None:
self.name = name
async def __call__(self, handler, event, data):
@@ -21,7 +23,7 @@ class StreamProbeMiddleware(BaseMiddleware):
class MiddlewareProbe(BaseMiddleware):
def __init__(self, inner: BaseMiddleware, name: str):
def __init__(self, inner: BaseMiddleware, name: str) -> None:
self.inner = inner
self.name = name
@@ -29,7 +31,7 @@ class MiddlewareProbe(BaseMiddleware):
now = time.perf_counter()
t0 = data.setdefault("_mw_t0", now)
prev = data.setdefault("_mw_prev", now)
logger.info(f"[mw:{self.name}] +{(now - prev)*1000:.2f} ms total {(now - t0)*1000:.2f} ms")
logger.info(f"[mw:{self.name}] +{(now - prev) * 1000:.2f} ms total {(now - t0) * 1000:.2f} ms")
downstream_ms = 0.0
@@ -54,14 +56,14 @@ class MiddlewareProbe(BaseMiddleware):
class TailHandlerProbe(BaseMiddleware):
def __init__(self, name: str = "handler"):
def __init__(self, name: str = "handler") -> None:
self.name = name
async def __call__(self, handler, event, data):
now = time.perf_counter()
t0 = data.setdefault("_mw_t0", now)
prev = data.setdefault("_mw_prev", now)
logger.info(f"[mw:{self.name}:enter] +{(now - prev)*1000:.2f} ms total {(now - t0)*1000:.2f} ms")
logger.info(f"[mw:{self.name}:enter] +{(now - prev) * 1000:.2f} ms total {(now - t0) * 1000:.2f} ms")
start = time.perf_counter()
try:
return await handler(event, data)
+2 -2
View File
@@ -1,9 +1,9 @@
from aiohttp.web_urldispatcher import UrlDispatcher
from utils.modules_loader import load_module_webhooks
from handlers.payments.heleket.webhook import heleket_webhook
from handlers.payments.kassai.webhook import kassai_webhook
from utils.modules_loader import load_module_webhooks
from .wata_payment import wata_payment_webhook