Compare commits

...

5 Commits

Author SHA1 Message Date
a2509c629e fixup! fix registration,add filter
All checks were successful
continuous-integration/drone/push Build is passing
2025-09-25 22:46:24 +03:00
2307637c80 separate FSM 2025-09-25 22:44:59 +03:00
631e7b4c13 fix imports 2025-09-25 22:43:41 +03:00
9fae1cbe1c fix registration,add filter 2025-09-25 22:41:11 +03:00
bbf2b1e6f9 fix session middleware 2025-09-25 22:37:54 +03:00
9 changed files with 69 additions and 50 deletions

4
app/FSM/__init__.py Normal file
View File

@@ -0,0 +1,4 @@
from .states import OrderForm, SearchForm, OrderingForm
__all__ = ["SearchForm", "OrderForm", "OrderingForm"]

24
app/FSM/states.py Normal file
View File

@@ -0,0 +1,24 @@
from aiogram.fsm.state import State, StatesGroup
class SearchForm(StatesGroup):
search_option = State()
data_to_search = State()
search_result = State()
class OrderForm(StatesGroup):
id = State()
worker_id = State()
status_id = State()
counterparty = State()
customer = State()
commencement_work = State()
end_work = State()
description = State()
class OrderingForm(StatesGroup):
tools_list = State()

View File

@@ -23,3 +23,7 @@ class CommandFilter(BaseFilter):
async def __call__(self, message: Message) -> bool: async def __call__(self, message: Message) -> bool:
return message.text.startswith(tuple(self.commands.keys())) return message.text.startswith(tuple(self.commands.keys()))
class IsRegister(BaseFilter):
async def __call__(self, message: Message | CallbackQuery, **data: dict[str, Any]) -> bool:
return data.get("through_registration") is True

View File

@@ -1,11 +1,9 @@
import time
import re import re
from aiogram import Router, Bot, F
from aiogram.types import (Message, ChatMemberUpdated, FSInputFile, CallbackQuery, ReplyKeyboardRemove)
from loguru import logger from loguru import logger
from aiogram import Router, Bot, F
from aiogram.types import Message, CallbackQuery
from handlers.registration import registration_confirm from handlers.registration import registration_confirm
from filters.Filters import IsAdmin, CommandFilter from filters.Filters import IsAdmin
from database import async_session_
admin_router = Router() admin_router = Router()

View File

@@ -33,24 +33,6 @@ find_order_params = {"search_by_name": "Поиск по названию", "sear
"search_by_id": "Поиск по номеру заказа", "search_by_customer": "Поиск по заказчику"} "search_by_id": "Поиск по номеру заказа", "search_by_customer": "Поиск по заказчику"}
class SearchForm(StatesGroup):
search_option = State()
data_to_search = State()
search_result = State()
class OrderForm(StatesGroup):
id = State()
worker_id = State()
status_id = State()
counterparty = State()
customer = State()
commencement_work = State()
end_work = State()
description = State()
@orders_router.message(Command(commands="orders")) @orders_router.message(Command(commands="orders"))
async def orders_menu(message: Message): async def orders_menu(message: Message):
order_main_upd = order_main_update if await IsAdmin()(message) else {} order_main_upd = order_main_update if await IsAdmin()(message) else {}

View File

@@ -1,17 +1,18 @@
import os import os
from asyncio import Event, wait_for, TimeoutError from asyncio import Event, wait_for, TimeoutError
from aiogram import Router, Bot from aiogram import Router, Bot
from aiogram.filters import CommandStart from aiogram.filters import CommandStart
from aiogram.types import Message, User from aiogram.types import Message, User
from sqlalchemy import insert, select from sqlalchemy import insert, select
from loguru import logger
from keyboards import create_inline_kb from keyboards import create_inline_kb
from database import async_session_, Worker from database import async_session_, Worker
from filters import IsRegister
registration_router = Router() registration_router = Router()
registration_router.message.filter(IsRegister() or CommandStart())
registration_confirm: dict[int, Event] = {} registration_confirm: dict[int, Event] = {}
user_info_template = ("Новый пользователь ждет регистрации:\n" user_info_template = ("Новый пользователь ждет регистрации:\n"
"Имя: {}\n" "Имя: {}\n"
@@ -23,13 +24,11 @@ admins_ids = list(map(int, os.getenv("BOT_ADMINS").split(",")))
@registration_router.message(CommandStart()) @registration_router.message(CommandStart())
async def registration_command(message: Message, bot: Bot): async def start_command(message: Message, bot: Bot):
async with async_session_() as session: async with async_session_() as session:
async with session.begin():
result = await session.execute(select(Worker).where(Worker.telegram_id == message.from_user.id)) result = await session.execute(select(Worker).where(Worker.telegram_id == message.from_user.id))
user = result.scalars().first() user = result.scalars().first()
if not user: if not user:
user = message.from_user user = message.from_user
dict_for_inline = {f'reg_@{user.id}': 'Allow', f'del_@{user.id}': 'Reject'} dict_for_inline = {f'reg_@{user.id}': 'Allow', f'del_@{user.id}': 'Reject'}
user_info = user_info_template.format(user.first_name, user.last_name if user.last_name else 'Не указана', user_info = user_info_template.format(user.first_name, user.last_name if user.last_name else 'Не указана',
@@ -39,8 +38,11 @@ async def registration_command(message: Message, bot: Bot):
await bot.send_message(chat_id=admin, text=user_info) await bot.send_message(chat_id=admin, text=user_info)
await bot.send_message(chat_id=admin, text='Зарегистрировать пользователя', await bot.send_message(chat_id=admin, text='Зарегистрировать пользователя',
reply_markup=create_inline_kb(width=2, **dict_for_inline)) reply_markup=create_inline_kb(width=2, **dict_for_inline))
except Exception as err: await message.answer("Запрос на регистрацию отправлен администратору, ожидайте подтверждения.")
pass
except Exception:
logger.error(f"{start_command.__name__} failed")
reg_confirm = Event() reg_confirm = Event()
registration_confirm[user.id] = reg_confirm registration_confirm[user.id] = reg_confirm
try: try:
@@ -49,7 +51,7 @@ async def registration_command(message: Message, bot: Bot):
async with local_session.begin(): async with local_session.begin():
local_session.add(Worker(telegram_id=user.id, name=user.first_name)) local_session.add(Worker(telegram_id=user.id, name=user.first_name))
await message.answer("Регистрация подтверждена") await message.answer("Регистрация подтверждена, для просмотра доступных действий нажмите кнопку 'MENU'")
except TimeoutError: except TimeoutError:
await message.answer("Время ожидания истекло.") await message.answer("Время ожидания истекло.")
@@ -57,3 +59,8 @@ async def registration_command(message: Message, bot: Bot):
else: else:
await message.answer("Работа бота возобновлена") await message.answer("Работа бота возобновлена")
@registration_router.message()
async def catch_message(message: Message):
await message.answer("Для работы с ботом, требуется регистрация\nНажмите /start для регистрации")

View File

@@ -4,7 +4,7 @@ from dotenv import load_dotenv
from aiogram import Dispatcher, Bot from aiogram import Dispatcher, Bot
from handlers import * from handlers import *
from keyboards import set_main_menu from keyboards import set_main_menu
from middlewares import AccessCheckMiddleware from middlewares import SessionMiddleware
load_dotenv(".env") load_dotenv(".env")
bot = Bot(token=os.getenv("TOKEN")) bot = Bot(token=os.getenv("TOKEN"))
@@ -16,7 +16,7 @@ async def main() -> None:
dp.startup.register(set_main_menu) dp.startup.register(set_main_menu)
dp.include_router(registration_router) dp.include_router(registration_router)
dp.include_router(admin_router) dp.include_router(admin_router)
dp.update.outer_middleware(AccessCheckMiddleware()) dp.update.outer_middleware(SessionMiddleware())
dp.include_router(orders_router) dp.include_router(orders_router)
dp.include_router(components_router) dp.include_router(components_router)

View File

@@ -1,4 +1,4 @@
from .outer_middlewares import AccessCheckMiddleware from .outer_middlewares import SessionMiddleware
__all__ = ["AccessCheckMiddleware"] __all__ = ["SessionMiddleware"]

View File

@@ -1,29 +1,29 @@
import logging
from typing import Any, Awaitable, Callable, Dict from typing import Any, Awaitable, Callable, Dict
from aiogram import BaseMiddleware, Bot from aiogram import BaseMiddleware, Bot
from aiogram.types import TelegramObject from aiogram.types import TelegramObject
from database import async_session_, Worker
from sqlalchemy import select from sqlalchemy import select
from loguru import logger
from database import async_session_, Worker
class SessionMiddleware(BaseMiddleware):
class AccessCheckMiddleware(BaseMiddleware):
sessions_in_memory_db = set() sessions_in_memory_db = set()
async def __call__( async def __call__(
self, self,
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]], handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
event: TelegramObject, event: TelegramObject,
data: Dict[str, Any] data: Dict[str, Any]
) -> Any: ) -> Any:
logger.info("Session check")
event_data = event.message or event.callback_query event_data = event.message or event.callback_query
user = event_data.from_user.id user = event_data.from_user.id
if user not in self.sessions_in_memory_db: if user not in self.sessions_in_memory_db:
async with async_session_() as session: async with async_session_() as session:
async with session.begin():
result = await session.execute(select(Worker).where(Worker.telegram_id == event_data.from_user.id)) result = await session.execute(select(Worker).where(Worker.telegram_id == event_data.from_user.id))
user = result.scalars().first() user_in_db = result.scalars().first()
if user: if not user_in_db:
self.sessions_in_memory_db.add(event_data.from_user.id) data["through_registration"] = True
else:
self.sessions_in_memory_db.add(user)
return await handler(event, data) return await handler(event, data)
return None