init
This commit is contained in:
0
routers/__init__.py
Normal file
0
routers/__init__.py
Normal file
83
routers/auth_router.py
Normal file
83
routers/auth_router.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from aiogram import Router, F, Bot
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
from repos.user_repo import UsersRepo, UserStatus
|
||||
from keyboards import get_admin_decision_kb
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
# Чтобы IDE не ругалась, переменные инициализируются в main,
|
||||
# но здесь мы ожидаем, что они будут переданы или доступны через DI (workflow_data)
|
||||
# В этом примере я буду доставать их из data, переданной диспетчером, или глобально (для простоты примера - глобально в рамках архитектуры aiogram лучше через middleware DI).
|
||||
# Для простоты доступа предположим, что repo и admin_id прокинуты.
|
||||
|
||||
|
||||
|
||||
@router.callback_query(F.data == "req_access")
|
||||
async def user_request_access(callback: CallbackQuery, repo: UsersRepo, bot: Bot, admin_id: int):
|
||||
"""Пользователь нажал 'Запросить доступ'"""
|
||||
user = callback.from_user
|
||||
|
||||
# Двойная проверка на 24 часа (на случай если пользователь не обновлял сообщение)
|
||||
if not await repo.can_request_access(user.id):
|
||||
await callback.answer("⏳ Вы уже отправляли запрос недавно. Повторите через сутки.", show_alert=True)
|
||||
return
|
||||
|
||||
# 1. Записываем в БД статус PENDING
|
||||
await repo.create_or_update_request(user)
|
||||
|
||||
# 2. Уведомляем пользователя
|
||||
await callback.message.edit_text("✅ Заявка отправлена администратору. Ожидайте решения.")
|
||||
|
||||
# 3. Отправляем уведомление Админу
|
||||
# Формируем красивый текст
|
||||
info = (
|
||||
f"🔔 <b>Новый запрос доступа!</b>\n"
|
||||
f"👤 Имя: {user.full_name}\n"
|
||||
f"🆔 ID: <code>{user.id}</code>\n"
|
||||
f"🔗 Username: @{user.username if user.username else 'нет'}"
|
||||
)
|
||||
|
||||
await bot.send_message(
|
||||
chat_id=admin_id,
|
||||
text=info,
|
||||
reply_markup=get_admin_decision_kb(user.id)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("access_"))
|
||||
async def admin_decision(callback: CallbackQuery, repo: UsersRepo, bot: Bot):
|
||||
"""Админ нажал Разрешить или Запретить"""
|
||||
action, user_id_str = callback.data.split("_")[1], callback.data.split("_")[2]
|
||||
target_user_id = int(user_id_str)
|
||||
|
||||
if action == "allow":
|
||||
# Обновляем БД
|
||||
await repo.set_status(target_user_id, UserStatus.ALLOWED)
|
||||
|
||||
# Ответ админу
|
||||
await callback.message.edit_text(f"✅ Доступ для {target_user_id} <b>РАЗРЕШЕН</b>.")
|
||||
|
||||
# Уведомление пользователю
|
||||
try:
|
||||
await bot.send_message(target_user_id, "🎉 <b>Вам предоставлен доступ к боту!</b>\nНажмите /start")
|
||||
except:
|
||||
await callback.message.answer(
|
||||
f"⚠️ Не удалось уведомить пользователя {target_user_id} (он заблокировал бота?)")
|
||||
|
||||
elif action == "deny":
|
||||
# Обновляем БД (статус DENIED, дата запроса остается старой - то есть через сутки он сможет снова попросить)
|
||||
# Если хотите, чтобы при отказе таймер 24ч сбрасывался на "сейчас", нужно обновить last_request_date.
|
||||
# В текущей реализации repo, мы просто меняем статус. Таймер тикает от момента подачи заявки пользователем.
|
||||
|
||||
await repo.set_status(target_user_id, UserStatus.DENIED)
|
||||
|
||||
await callback.message.edit_text(f"🚫 Доступ для {target_user_id} <b>ЗАПРЕЩЕН</b>.")
|
||||
|
||||
try:
|
||||
await bot.send_message(target_user_id, "🚫 Администратор отклонил ваш запрос доступа.")
|
||||
except:
|
||||
pass
|
||||
|
||||
await callback.answer()
|
||||
48
routers/char_router.py
Normal file
48
routers/char_router.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from aiogram.filters import Command
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.types import *
|
||||
from aiogram import Router, F
|
||||
|
||||
from models.Character import Character
|
||||
from repos.dao import DAO
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
class States(StatesGroup):
|
||||
char_wait_name = State()
|
||||
char_wait_bio = State()
|
||||
|
||||
|
||||
@router.message(F.document, Command("add_char"))
|
||||
async def add_char(message: Message, state: FSMContext, dao: DAO):
|
||||
await state.set_data({"photo": bot.download(file=message.document.file_id)})
|
||||
await state.set_state(States.char_wait_name)
|
||||
await message.answer("Кайф, теперь напиши ее имя")
|
||||
|
||||
|
||||
@router.callback_query(States.char_wait_name)
|
||||
async def new_char_name(message: Message, state: FSMContext, dao: DAO):
|
||||
await state.set_data({"name": message.text})
|
||||
await state.set_state(States.char_wait_bio)
|
||||
await message.answer("А теперь напиши био. Хоть чуть чуть.")
|
||||
|
||||
|
||||
@router.callback_query(States.char_wait_bio)
|
||||
async def new_char_bio(message: Message, state: FSMContext, dao: DAO):
|
||||
data = await state.get_data()
|
||||
photo = data["photo"]
|
||||
name = data["name"]
|
||||
char = Character(id=None, name=name, character_image=photo, character_bio=message.text)
|
||||
await dao.chars.add_character(char)
|
||||
await message.answer_photo(photo=BufferedInputFile(char.character_image, "img.png"), caption="Персонаж создан!\n"
|
||||
f"Имя:{char.name}\n"
|
||||
f"Био: {char.character_bio}\n"
|
||||
)
|
||||
|
||||
|
||||
@router.message(Command("add_char"))
|
||||
async def add_char_cmd(message: Message):
|
||||
await message.answer(
|
||||
"Добавление персонажа производится через отправку документа-фото исходного изображения персонажа.")
|
||||
55
routers/gen_router.py
Normal file
55
routers/gen_router.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import asyncio
|
||||
|
||||
from aiogram import Router, Bot, F
|
||||
from aiogram.enums import ParseMode
|
||||
from aiogram.filters import *
|
||||
from aiogram.types import *
|
||||
|
||||
from adapters.google_adapter import GoogleAdapter
|
||||
|
||||
router = Router()
|
||||
|
||||
@router.message(Command("image"))
|
||||
async def cmd_image_gen(message: Message, command: CommandObject, gemini: GoogleAdapter, bot: Bot):
|
||||
# ... ваш код ...
|
||||
# Обратите внимание: gemini теперь прилетает аргументом, так как мы сделали dp["gemini"]
|
||||
prompt = command.args
|
||||
if not prompt:
|
||||
await message.answer("⚠️ Напиши промпт.")
|
||||
return
|
||||
|
||||
wait_msg = await message.answer("🎨 Генерирую...")
|
||||
|
||||
# Получение байтов фото (логика та же)
|
||||
image_bytes = None
|
||||
if message.photo:
|
||||
file_io = await bot.download(message.photo[-1].file_id)
|
||||
image_bytes = file_io.getvalue()
|
||||
elif message.reply_to_message and message.reply_to_message.photo:
|
||||
file_io = await bot.download(message.reply_to_message.photo[-1].file_id)
|
||||
image_bytes = file_io.getvalue()
|
||||
|
||||
result = await asyncio.to_thread(
|
||||
gemini.generate, prompt=prompt, image_bytes=image_bytes, generate_image=True
|
||||
)
|
||||
|
||||
await wait_msg.delete()
|
||||
|
||||
if result.get("images"):
|
||||
for img in result["images"]:
|
||||
await message.answer_document(BufferedInputFile(img.read(), "img.png"))
|
||||
elif result.get("text"):
|
||||
await message.answer(result["text"])
|
||||
else:
|
||||
await message.answer(f"Ошибка: {result.get('error', 'Unknown')}")
|
||||
|
||||
|
||||
@router.message(F.text)
|
||||
async def handle_text(message: Message, gemini: GoogleAdapter, bot: Bot):
|
||||
await bot.send_chat_action(message.chat.id, "typing")
|
||||
result = await asyncio.to_thread(gemini.generate, prompt=message.text)
|
||||
if result.get("text"):
|
||||
await message.answer(result["text"], parse_mode=ParseMode.MARKDOWN)
|
||||
else:
|
||||
await message.answer("Ошибка генерации")
|
||||
|
||||
Reference in New Issue
Block a user