Skip to content

Commit

Permalink
added join to team by join to chat
Browse files Browse the repository at this point in the history
  • Loading branch information
bomzheg committed Jul 30, 2023
1 parent ce59015 commit 6764e9d
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 25 deletions.
6 changes: 6 additions & 0 deletions shvatka/core/services/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ async def join_team(
await dao.commit()
raise
await dao.commit()
logger.info(
"Captain %s added to team %s player %s",
manager.id,
team.id,
player.id,
)


async def get_checked_player_on_team(
Expand Down
4 changes: 3 additions & 1 deletion shvatka/tgbot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ async def main():

logger.info("started")
try:
await dp.start_polling(bot)
await dp.start_polling(
bot, allowed_updates=dp.resolve_used_update_types(skip_events={"aiogd_update"})
)
finally:
await engine.dispose()
logger.info("stopped")
Expand Down
178 changes: 154 additions & 24 deletions shvatka/tgbot/handlers/team/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,30 @@
from aiogram import Bot, F, Router
from aiogram.enums import ChatType
from aiogram.exceptions import TelegramBadRequest
from aiogram.filters import Command, CommandObject, or_f
from aiogram.types import Message
from aiogram.filters import (
Command,
CommandObject,
or_f,
ChatMemberUpdatedFilter,
IS_NOT_MEMBER,
IS_MEMBER,
)
from aiogram.types import Message, ChatMemberUpdated, CallbackQuery
from aiogram.utils.text_decorations import html_decoration as hd

from shvatka.core.models import dto
from shvatka.core.services.player import join_team, get_team_players
from shvatka.core.services.player import get_team_players, get_player_by_id, join_team
from shvatka.core.services.team import create_team
from shvatka.core.utils import exceptions
from shvatka.core.utils.defaults_constants import DEFAULT_ROLE
from shvatka.core.utils.exceptions import (
TeamError,
PlayerAlreadyInTeam,
AnotherTeamInChat,
PlayerRestoredInTeam,
PermissionsError,
)
from shvatka.core.views.game import GameLogWriter
from shvatka.infrastructure.db.dao.holder import HolderDao
from shvatka.tgbot import keyboards as kb
from shvatka.tgbot import states
from shvatka.tgbot.filters.has_target import HasTargetFilter
from shvatka.tgbot.filters.is_admin import is_admin_filter
Expand Down Expand Up @@ -87,15 +94,26 @@ async def cmd_create_team_group(message: Message, user: dto.User, chat: dto.Chat
await message.reply(NOT_SUPERGROUP_ERROR)


async def user_join_chat_with_team(
event: ChatMemberUpdated, team: dto.Team, player: dto.Player, bot: Bot
) -> None:
await bot.send_message(
chat_id=event.chat.id,
text=f"Принять {hd.quote(player.name_mention)} в команду {hd.quote(team.name)}?",
reply_markup=kb.get_join_team_kb(team, player),
)


async def cmd_add_in_team(
message: Message,
_: Message,
team: dto.Team,
target: dto.Player,
player: dto.Player,
bot: Bot,
command: CommandObject,
dao: HolderDao,
):
role = command.args or DEFAULT_ROLE
logger.info(
"Captain %s try to add %s in team %s",
player.id,
Expand All @@ -105,41 +123,131 @@ async def cmd_add_in_team(
try:
chat_member = await bot.get_chat_member(team.get_chat_id(), target.get_chat_id())
except TelegramBadRequest:
return await message.reply("Не могу найти этого пользователя (его нет в чате?)")
return await bot.send_message(
chat_id=team.get_chat_id(), text="Не могу найти этого пользователя (его нет в чате?)"
)
if chat_member.user.is_bot:
return
if chat_member.status == "left":
return await message.reply("Не могу добавить этого пользователя. Вероятно его нет в чате")
role = command.args or DEFAULT_ROLE
return await bot.send_message(
chat_id=team.get_chat_id(),
text="Не могу добавить этого пользователя. Вероятно его нет в чате",
)
try:
await join_team(target, team, player, dao.team_player, role)
except PlayerAlreadyInTeam as e:
return await message.reply(
f"Игрок {hd.quote(target.name_mention)} уже находится в команде "
f"({hd.quote(e.team.name)}).\n" # type: ignore
return await bot.send_message(
chat_id=team.get_chat_id(),
text=f"Игрок {hd.quote(target.name_mention)} уже находится в команде "
f"({hd.quote(e.team.name)}).\n", # type: ignore
)
except PlayerRestoredInTeam:
return await message.reply("Игрок возвращён в команду, я сделаю вид что и не покидал")
except PermissionsError:
return await message.reply(
"У тебя нет прав добавлять игроков в команду. Обратись к капитану"
except exceptions.PlayerRestoredInTeam:
return await bot.send_message(
chat_id=team.get_chat_id(),
text="Игрок возвращён в команду, я сделаю вид что и не покидал",
)
except exceptions.PermissionsError:
return await bot.send_message(
chat_id=team.get_chat_id(),
text="У тебя нет прав добавлять игроков в команду. Обратись к капитану",
)

await message.answer(
"В команду {team} добавлен игрок "
"{player} в качестве роли указано: {role}".format(
await bot.send_message(
chat_id=team.get_chat_id(),
text="В команду {team} добавлен игрок {player} в качестве роли указано: {role}".format(
team=hd.bold(team.name), player=hd.bold(target.name_mention), role=hd.italic(role)
)
),
)


async def button_join(
callback_query: CallbackQuery,
callback_data: kb.JoinToTeamRequestCD,
team: dto.Team,
player: dto.Player,
team_player: dto.TeamPlayer,
bot: Bot,
dao: HolderDao,
):
if team.id != callback_data.team_id:
raise exceptions.SHDataBreach(
f"asked about team_id {callback_data.team_id} but in team {team.id}"
)
if team_player.team_id != team.id:
return await callback_query.answer("Ты состоишь в другой команде!", show_alert=True)
await callback_query.answer()
target = await get_player_by_id(callback_data.player_id, dao.player)
logger.info(
"Captain %s add to team %s player %s with role %s",
"Captain %s try to add %s in team %s",
player.id,
team.id,
target.id,
role,
team.id,
)
chat_member = await bot.get_chat_member(team.get_chat_id(), target.get_chat_id())
if chat_member.user.is_bot:
return
if chat_member.status == "left":
return await bot.send_message(
chat_id=team.get_chat_id(),
text="Не могу добавить этого пользователя. Вероятно его уже нет в чате",
)
assert callback_query.message
try:
await join_team(target, team, player, dao.team_player)
except PlayerAlreadyInTeam as e:
return await bot.edit_message_text(
chat_id=team.get_chat_id(),
message_id=callback_query.message.message_id,
text=f"Игрок {hd.quote(target.name_mention)} уже находится в команде "
f"({hd.quote(e.team.name)}).\n", # type: ignore
)
except exceptions.PlayerRestoredInTeam:
return await bot.edit_message_text(
chat_id=team.get_chat_id(),
message_id=callback_query.message.message_id,
text="Игрок возвращён в команду, я сделаю вид что и не покидал",
)
except exceptions.PermissionsError:
return await callback_query.answer(
text="У тебя нет прав добавлять игроков в команду. Обратись к капитану",
show_alert=True,
)
await bot.edit_message_text(
chat_id=team.get_chat_id(),
message_id=callback_query.message.message_id,
text="В команду {team} добавлен игрок {player}".format(
team=hd.bold(team.name), player=hd.bold(target.name_mention)
),
)


async def button_join_no(
callback_query: CallbackQuery,
callback_data: kb.JoinToTeamRequestCD,
team: dto.Team,
player: dto.Player,
team_player: dto.TeamPlayer,
dao: HolderDao,
):
if team.id != callback_data.team_id:
raise exceptions.SHDataBreach(
f"asked about team_id {callback_data.team_id} but in team {team.id}"
)
if team_player.team_id != team.id:
return await callback_query.answer("Ты состоишь в другой команде!", show_alert=True)
await callback_query.answer()
target = await get_player_by_id(callback_data.player_id, dao.player)
assert callback_query.message
await callback_query.message.edit_text(
f"{hd.quote(player.name_mention)} не стал принимать "
f"игрока {hd.quote(target.name_mention)} в команду"
)


async def answer_not_enough_rights(callback_query: CallbackQuery):
await callback_query.answer("Недостаточно прав", show_alert=True)


async def cmd_team(message: Message, team: dto.Team):
await message.answer(
text=render_team_card(team),
Expand All @@ -158,6 +266,7 @@ async def cmd_players(message: Message, team: dto.Team, dao: HolderDao):
def setup() -> Router:
router = Router(name=__name__)
router.message.outer_middleware.register(TeamPlayerMiddleware())
router.callback_query.outer_middleware.register(TeamPlayerMiddleware())
disable_router_on_game(router)

router.message.register(
Expand Down Expand Up @@ -187,6 +296,27 @@ def setup() -> Router:
Command(commands=PLAYERS_COMMAND),
IsTeamFilter(),
)
router.chat_member.register(
user_join_chat_with_team,
ChatMemberUpdatedFilter(IS_NOT_MEMBER >> IS_MEMBER),
IsTeamFilter(),
)
router.callback_query.register(
button_join,
kb.JoinToTeamRequestCD.filter(F.y_n),
or_f(TeamPlayerFilter(is_captain=True), TeamPlayerFilter(can_add_players=True)),
IsTeamFilter(),
)
router.callback_query.register(
button_join_no,
kb.JoinToTeamRequestCD.filter(~F.y_n),
or_f(TeamPlayerFilter(is_captain=True), TeamPlayerFilter(can_add_players=True)),
IsTeamFilter(),
)
router.callback_query.register(
answer_not_enough_rights,
kb.JoinToTeamRequestCD.filter(),
)
register_start_handler(
Command(commands=MANAGE_TEAM_COMMAND),
F.chat.type == ChatType.PRIVATE,
Expand Down
4 changes: 4 additions & 0 deletions shvatka/tgbot/keyboards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
get_kb_agree_promotion,
AgreePromotionCD,
)
from .team import (
JoinToTeamRequestCD,
get_join_team_kb,
)
from .waiver import (
get_kb_waivers,
get_kb_manage_waivers,
Expand Down
24 changes: 24 additions & 0 deletions shvatka/tgbot/keyboards/team.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from aiogram.filters.callback_data import CallbackData
from aiogram.utils.keyboard import InlineKeyboardBuilder

from shvatka.core.models import dto


class JoinToTeamRequestCD(CallbackData, prefix="join_to_team"):
team_id: int
player_id: int
y_n: bool


def get_join_team_kb(team: dto.Team, player: dto.Player):
builder = InlineKeyboardBuilder()
builder.button(
text="Принять",
callback_data=JoinToTeamRequestCD(team_id=team.id, player_id=player.id, y_n=True),
)
builder.button(
text="Отказать",
callback_data=JoinToTeamRequestCD(team_id=team.id, player_id=player.id, y_n=False),
)
builder.adjust(2)
return builder.as_markup()

0 comments on commit 6764e9d

Please sign in to comment.