feat: init

This commit is contained in:
h
2026-04-16 01:16:54 +02:00
commit 14bf1047ee
51 changed files with 2227 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
from uuid import uuid4
from aiogram import Bot, F, Router
from aiogram.types import CallbackQuery, Message
from aiogram.utils.deep_linking import create_start_link
from bot.factories import SettingsAction, SettingsCallback
from bot.filters import ChannelOwnerFilter
from bot.keyboards import channel_settings_kb, invite_mode_kb, members_kb
from utils.db.models import Channel, Invite
router = Router()
def settings_text(channel: Channel) -> str:
return f"⚙️ <b>{channel.title}</b>"
def members_text(channel: Channel) -> str:
return f"👥 <b>{channel.title}</b>"
async def refresh_channel(channel: Channel) -> Channel:
return await Channel.get_by_id(channel.id) or channel
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.MAIN), ChannelOwnerFilter()
)
async def show_settings(callback: CallbackQuery, channel: Channel):
if not isinstance(callback.message, Message):
return
await callback.message.edit_text(
settings_text(channel), reply_markup=channel_settings_kb(channel)
)
await callback.answer()
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.MEMBERS), ChannelOwnerFilter()
)
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.PAGE), ChannelOwnerFilter()
)
async def show_members(
callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel
):
if not isinstance(callback.message, Message):
return
if not channel.members:
await callback.answer("Нет участников.", show_alert=True)
return
await callback.message.edit_text(
members_text(channel), reply_markup=members_kb(channel, callback_data.page)
)
await callback.answer()
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.MODE_TOGGLE),
ChannelOwnerFilter(),
)
async def toggle_member_mode(
callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel
):
if not isinstance(callback.message, Message):
return
member = channel.get_member(callback_data.user_id)
if member is None:
await callback.answer("Участник не найден.", show_alert=True)
return
next_mode = "approval" if member.mode == "instant" else "instant"
await channel.set_member_mode(callback_data.user_id, next_mode)
refreshed = await refresh_channel(channel)
await callback.message.edit_reply_markup(
reply_markup=members_kb(refreshed, callback_data.page)
)
await callback.answer()
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.KICK), ChannelOwnerFilter()
)
async def kick_member(
callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel
):
if not isinstance(callback.message, Message):
return
await channel.remove_member(callback_data.user_id)
refreshed = await refresh_channel(channel)
if refreshed.members:
await callback.message.edit_reply_markup(
reply_markup=members_kb(refreshed, callback_data.page)
)
else:
await callback.message.edit_text(
settings_text(refreshed), reply_markup=channel_settings_kb(refreshed)
)
await callback.answer()
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.INVITE_MODE),
ChannelOwnerFilter(),
)
async def show_invite_modes(callback: CallbackQuery, channel: Channel):
if not isinstance(callback.message, Message):
return
await callback.message.edit_text(
f"🔗 Режим для нового участника <b>{channel.title}</b>:",
reply_markup=invite_mode_kb(channel.id),
)
await callback.answer()
@router.callback_query(
SettingsCallback.filter(F.action == SettingsAction.INVITE_CREATE),
ChannelOwnerFilter(),
)
async def create_invite(
callback: CallbackQuery, callback_data: SettingsCallback, channel: Channel, bot: Bot
):
if not isinstance(callback.message, Message):
return
if callback_data.mode == "approval":
mode = "approval"
elif callback_data.mode == "instant":
mode = "instant"
else:
await callback.answer("Неверный режим.", show_alert=True)
return
invite = Invite(code=uuid4().hex[:12], channel_id=channel.id, mode=mode)
await invite.insert()
link = await create_start_link(bot, f"inv_{invite.code}", encode=True)
mode_label = "сразу" if mode == "instant" else "после проверки"
await callback.message.edit_text(
f"🔗 Инвайт для <b>{channel.title}</b> (режим: {mode_label}):\n\n"
f"<code>{link}</code>",
reply_markup=channel_settings_kb(channel),
)
await callback.answer()