smart-bot-factory 0.2.10__py3-none-any.whl → 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of smart-bot-factory might be problematic. Click here for more details.
- smart_bot_factory/cli.py +35 -64
- smart_bot_factory/core/bot_utils.py +69 -21
- smart_bot_factory/core/decorators.py +377 -143
- smart_bot_factory/core/router.py +7 -4
- smart_bot_factory/creation/bot_builder.py +47 -14
- smart_bot_factory/handlers/handlers.py +5 -4
- smart_bot_factory/router/__init__.py +2 -3
- smart_bot_factory-0.3.1.dist-info/METADATA +905 -0
- {smart_bot_factory-0.2.10.dist-info → smart_bot_factory-0.3.1.dist-info}/RECORD +12 -13
- smart_bot_factory/core/telegram_router.py +0 -58
- smart_bot_factory-0.2.10.dist-info/METADATA +0 -789
- {smart_bot_factory-0.2.10.dist-info → smart_bot_factory-0.3.1.dist-info}/WHEEL +0 -0
- {smart_bot_factory-0.2.10.dist-info → smart_bot_factory-0.3.1.dist-info}/entry_points.txt +0 -0
- {smart_bot_factory-0.2.10.dist-info → smart_bot_factory-0.3.1.dist-info}/licenses/LICENSE +0 -0
smart_bot_factory/core/router.py
CHANGED
|
@@ -57,7 +57,7 @@ class EventRouter:
|
|
|
57
57
|
return wrapper
|
|
58
58
|
return decorator
|
|
59
59
|
|
|
60
|
-
def schedule_task(self, task_name: str, notify: bool = False, smart_check: bool = True, once_only: bool = True, delay: Union[str, int] = None, event_type: str = None):
|
|
60
|
+
def schedule_task(self, task_name: str, notify: bool = False, smart_check: bool = True, once_only: bool = True, delay: Union[str, int] = None, event_type: Union[str, Callable] = None):
|
|
61
61
|
"""
|
|
62
62
|
Декоратор для регистрации запланированной задачи в роутере
|
|
63
63
|
|
|
@@ -67,7 +67,9 @@ class EventRouter:
|
|
|
67
67
|
smart_check: Использовать ли умную проверку
|
|
68
68
|
once_only: Выполнять ли только один раз
|
|
69
69
|
delay: Время задержки в удобном формате (например, "1h 30m", "45m", 3600) - ОБЯЗАТЕЛЬНО
|
|
70
|
-
event_type:
|
|
70
|
+
event_type: Источник времени события - ОПЦИОНАЛЬНО:
|
|
71
|
+
- str: Тип события для поиска в БД (например, 'appointment_booking')
|
|
72
|
+
- Callable: Функция async def(user_id, user_data) -> datetime
|
|
71
73
|
"""
|
|
72
74
|
def decorator(func: Callable) -> Callable:
|
|
73
75
|
# Время ОБЯЗАТЕЛЬНО должно быть указано
|
|
@@ -115,7 +117,7 @@ class EventRouter:
|
|
|
115
117
|
return wrapper
|
|
116
118
|
return decorator
|
|
117
119
|
|
|
118
|
-
def global_handler(self, handler_type: str, notify: bool = False, once_only: bool = True, delay: Union[str, int] = None):
|
|
120
|
+
def global_handler(self, handler_type: str, notify: bool = False, once_only: bool = True, delay: Union[str, int] = None, event_type: Union[str, Callable] = None):
|
|
119
121
|
"""
|
|
120
122
|
Декоратор для регистрации глобального обработчика в роутере
|
|
121
123
|
|
|
@@ -147,7 +149,8 @@ class EventRouter:
|
|
|
147
149
|
'notify': notify,
|
|
148
150
|
'once_only': once_only,
|
|
149
151
|
'router': self.name,
|
|
150
|
-
'default_delay': default_delay_seconds
|
|
152
|
+
'default_delay': default_delay_seconds,
|
|
153
|
+
'event_type': event_type # Добавляем event_type для глобальных обработчиков
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
logger.info(f"🌍 Роутер {self.name}: зарегистрирован глобальный обработчик '{handler_type}': {func.__name__}")
|
|
@@ -317,25 +317,45 @@ class BotBuilder:
|
|
|
317
317
|
Регистрирует Telegram роутер для обработки команд и сообщений
|
|
318
318
|
|
|
319
319
|
Args:
|
|
320
|
-
telegram_router:
|
|
320
|
+
telegram_router: aiogram.Router для регистрации
|
|
321
|
+
|
|
322
|
+
Example:
|
|
323
|
+
from aiogram import Router
|
|
324
|
+
from aiogram.filters import Command
|
|
325
|
+
|
|
326
|
+
# Создаем обычный aiogram Router
|
|
327
|
+
my_router = Router(name="my_commands")
|
|
328
|
+
|
|
329
|
+
@my_router.message(Command("price"))
|
|
330
|
+
async def price_handler(message: Message):
|
|
331
|
+
await message.answer("Наши цены...")
|
|
332
|
+
|
|
333
|
+
# Регистрируем в боте
|
|
334
|
+
bot_builder.register_telegram_router(my_router)
|
|
321
335
|
"""
|
|
322
|
-
from
|
|
336
|
+
from aiogram import Router as AiogramRouter
|
|
323
337
|
|
|
324
|
-
if not isinstance(telegram_router,
|
|
325
|
-
raise TypeError(f"Ожидается
|
|
338
|
+
if not isinstance(telegram_router, AiogramRouter):
|
|
339
|
+
raise TypeError(f"Ожидается aiogram.Router, получен {type(telegram_router)}")
|
|
326
340
|
|
|
327
341
|
self._telegram_routers.append(telegram_router)
|
|
328
|
-
|
|
342
|
+
router_name = getattr(telegram_router, 'name', 'unnamed')
|
|
343
|
+
logger.info(f"✅ Telegram роутер '{router_name}' зарегистрирован в боте {self.bot_id}")
|
|
329
344
|
|
|
330
345
|
def register_telegram_routers(self, *telegram_routers):
|
|
331
346
|
"""
|
|
332
347
|
Регистрирует несколько Telegram роутеров одновременно
|
|
333
348
|
|
|
334
349
|
Args:
|
|
335
|
-
*telegram_routers: Произвольное количество
|
|
350
|
+
*telegram_routers: Произвольное количество aiogram.Router
|
|
336
351
|
|
|
337
352
|
Example:
|
|
338
|
-
|
|
353
|
+
from aiogram import Router
|
|
354
|
+
|
|
355
|
+
router1 = Router(name="commands")
|
|
356
|
+
router2 = Router(name="callbacks")
|
|
357
|
+
|
|
358
|
+
bot_builder.register_telegram_routers(router1, router2)
|
|
339
359
|
"""
|
|
340
360
|
if not telegram_routers:
|
|
341
361
|
logger.warning("⚠️ register_telegram_routers вызван без аргументов")
|
|
@@ -542,17 +562,23 @@ class BotBuilder:
|
|
|
542
562
|
"""
|
|
543
563
|
Регистрирует фильтр отправки (может блокировать отправку пользователю)
|
|
544
564
|
|
|
545
|
-
Если фильтр возвращает
|
|
565
|
+
Если фильтр возвращает True, сообщение НЕ отправляется
|
|
546
566
|
|
|
547
567
|
Args:
|
|
548
|
-
handler: async def(user_id: int
|
|
568
|
+
handler: async def(user_id: int) -> bool
|
|
549
569
|
|
|
550
570
|
Example:
|
|
551
571
|
@bot_builder.filter_send
|
|
552
|
-
async def block_during_process(user_id
|
|
572
|
+
async def block_during_process(user_id):
|
|
553
573
|
if is_processing(user_id):
|
|
554
|
-
return
|
|
555
|
-
return
|
|
574
|
+
return True # Блокируем отправку
|
|
575
|
+
return False # Разрешаем отправку
|
|
576
|
+
|
|
577
|
+
# Или совместимый с should_block_ai_response
|
|
578
|
+
@bot_builder.filter_send
|
|
579
|
+
async def should_block_ai_response(user_id):
|
|
580
|
+
# Ваша логика проверки
|
|
581
|
+
return user_is_blocked(user_id) # True = блокировать
|
|
556
582
|
"""
|
|
557
583
|
if not callable(handler):
|
|
558
584
|
raise TypeError(f"Обработчик должен быть callable, получен {type(handler)}")
|
|
@@ -682,8 +708,9 @@ class BotBuilder:
|
|
|
682
708
|
if self._telegram_routers:
|
|
683
709
|
logger.info(f"🔗 Подключаем {len(self._telegram_routers)} пользовательских Telegram роутеров")
|
|
684
710
|
for telegram_router in self._telegram_routers:
|
|
685
|
-
dp.include_router(telegram_router
|
|
686
|
-
|
|
711
|
+
dp.include_router(telegram_router)
|
|
712
|
+
router_name = getattr(telegram_router, 'name', 'unnamed')
|
|
713
|
+
logger.info(f"✅ Подключен Telegram роутер: {router_name}")
|
|
687
714
|
|
|
688
715
|
# Настраиваем стандартные обработчики (меньший приоритет)
|
|
689
716
|
setup_utils_handlers(dp) # Утилитарные команды (/status, /help)
|
|
@@ -712,6 +739,12 @@ class BotBuilder:
|
|
|
712
739
|
logger.info(f" 👑 Админов настроено: {len(self.config.ADMIN_TELEGRAM_IDS)}")
|
|
713
740
|
logger.info(f" 📝 Загружено промптов: {len(self.config.PROMPT_FILES)}")
|
|
714
741
|
|
|
742
|
+
# Запускаем фоновый процессор событий
|
|
743
|
+
from ..core.decorators import background_event_processor
|
|
744
|
+
import asyncio
|
|
745
|
+
asyncio.create_task(background_event_processor())
|
|
746
|
+
logger.info("✅ Фоновый процессор событий запущен (проверка БД каждую минуту)")
|
|
747
|
+
|
|
715
748
|
# Четкое сообщение о запуске
|
|
716
749
|
print(f"\n🤖 БОТ {self.bot_id.upper()} УСПЕШНО ЗАПУЩЕН!")
|
|
717
750
|
print(f"📱 Telegram Bot ID: {self.config.BOT_ID}")
|
|
@@ -64,9 +64,9 @@ async def start_handler(message: Message, state: FSMContext):
|
|
|
64
64
|
logger.error(f"Ошибка при обработке /start: {e}")
|
|
65
65
|
await send_message(message, "Произошла ошибка при инициализации. Попробуйте позже.")
|
|
66
66
|
|
|
67
|
-
@router.message(Command(commands=["timeup"]))
|
|
67
|
+
@router.message(Command(commands=["timeup", "вперед"]))
|
|
68
68
|
async def timeup_handler(message: Message, state: FSMContext):
|
|
69
|
-
"""Обработчик команды /timeup - тестирование запланированных событий"""
|
|
69
|
+
"""Обработчик команды /timeup (или /вперед) - тестирование запланированных событий"""
|
|
70
70
|
from ..core.decorators import process_scheduled_event, update_event_result
|
|
71
71
|
from datetime import datetime
|
|
72
72
|
|
|
@@ -753,8 +753,9 @@ async def process_user_message(message: Message, state: FSMContext, session_id:
|
|
|
753
753
|
for filter_func in send_filters:
|
|
754
754
|
try:
|
|
755
755
|
should_send = await filter_func(message.from_user.id)
|
|
756
|
-
if
|
|
757
|
-
|
|
756
|
+
if should_send:
|
|
757
|
+
# True = блокируем (для совместимости с should_block_ai_response)
|
|
758
|
+
logger.info(f"⛔ Фильтр '{filter_func.__name__}' заблокировал отправку (вернул True)")
|
|
758
759
|
return # Не отправляем
|
|
759
760
|
except Exception as e:
|
|
760
761
|
logger.error(f"❌ Ошибка в фильтре отправки '{filter_func.__name__}': {e}")
|
|
@@ -3,9 +3,8 @@ Router модули smart_bot_factory
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from ..core.router import EventRouter
|
|
6
|
-
from ..core.telegram_router import TelegramRouter
|
|
7
6
|
|
|
8
7
|
__all__ = [
|
|
9
|
-
'EventRouter', # Роутер для событий
|
|
10
|
-
|
|
8
|
+
'EventRouter', # Роутер для событий (бизнес-логика)
|
|
9
|
+
# Для Telegram используйте aiogram.Router напрямую
|
|
11
10
|
]
|