Skip to content

Commit

Permalink
Merge pull request #125 from Lamroy95/refactoring/create_chat_repo
Browse files Browse the repository at this point in the history
Move models
  • Loading branch information
bomzheg authored Oct 28, 2023
2 parents e319c6b + 9c32d55 commit 9fce1d8
Show file tree
Hide file tree
Showing 32 changed files with 789 additions and 538 deletions.
36 changes: 20 additions & 16 deletions app/filters/karma_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
from aiogram.filters import BaseFilter

from app.config.karmic_triggers import (
PLUS,
PLUS_TRIGGERS,
PLUS_EMOJI,
MINUS,
MINUS_EMOJI,
MINUS_TRIGGERS,
PLUS,
PLUS_EMOJI,
PLUS_TRIGGERS,
)
from app.models.db import ChatSettings
from app.infrastructure.database.models import ChatSettings

PUNCTUATIONS = ",.!)"
INF = float('inf')
INF = float("inf")


@dataclass
Expand All @@ -25,7 +25,9 @@ class KarmaFilter(BaseFilter):
"""

async def __call__(
self, message: types.Message, chat_settings: ChatSettings,
self,
message: types.Message,
chat_settings: ChatSettings,
) -> dict[str, dict[str, float]]:
if chat_settings is None or not chat_settings.karma_counting:
return {}
Expand All @@ -39,7 +41,7 @@ async def check(message: types.Message) -> dict[str, dict[str, float]]:
karma_change, comment = get_karma_trigger(possible_trigger_text)
if karma_change is None:
return {}
rez = {'karma': {'karma_change': karma_change, 'comment': comment}}
rez = {"karma": {"karma_change": karma_change, "comment": comment}}
return rez


Expand Down Expand Up @@ -78,20 +80,22 @@ def has_plus_karma(possible_trigger: str) -> typing.Optional[float]:
if len(possible_trigger) == 0:
# blank line has no triggers
return None
if all([
len(possible_trigger) > 1,
possible_trigger[1:] == possible_trigger[:-1],
possible_trigger[0:len(PLUS)] == PLUS
]):
if all(
[
len(possible_trigger) > 1,
possible_trigger[1:] == possible_trigger[:-1],
possible_trigger[0 : len(PLUS)] == PLUS,
]
):
# contains only ++..+
return INF
if possible_trigger in PLUS_TRIGGERS:
return INF
if possible_trigger[0] in PLUS_EMOJI:
return INF
if possible_trigger[0:len(PLUS)] == PLUS:
if possible_trigger[0 : len(PLUS)] == PLUS:
try:
return +int(possible_trigger[len(PLUS):])
return +int(possible_trigger[len(PLUS) :])
except ValueError:
pass
return None
Expand All @@ -107,9 +111,9 @@ def has_minus_karma(possible_trigger: str) -> typing.Optional[float]:
# will never be true. Maybe we can remove it from condition
if not has_spaces(possible_trigger) and possible_trigger[0] in MINUS_EMOJI:
return -INF
if possible_trigger[0:len(MINUS)] == MINUS:
if possible_trigger[0 : len(MINUS)] == MINUS:
try:
return -int(possible_trigger[len(MINUS):])
return -int(possible_trigger[len(MINUS) :])
except ValueError:
pass
return None
Expand Down
41 changes: 29 additions & 12 deletions app/filters/tg_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from aiogram.enums import ChatMemberStatus
from aiogram.filters import BaseFilter

from app.models.db import Chat, User
from app.infrastructure.database.models import Chat
from app.services.find_target_user import get_target_user

logger = logging.getLogger(__name__)
Expand All @@ -18,6 +18,7 @@ class HasPermissions(BaseFilter):
"""
Validate the user has specified permissions in chat
"""

can_post_messages: bool = False
can_edit_messages: bool = False
can_delete_messages: bool = False
Expand All @@ -44,13 +45,19 @@ def __post_init__(self):
arg: True for arg in self.ARGUMENTS.values() if getattr(self, arg)
}

def _get_cached_value(self, user: types.User, chat: Chat) -> types.ChatMember | None:
def _get_cached_value(
self, user: types.User, chat: Chat
) -> types.ChatMember | None:
return None # TODO

def _set_cached_value(self, user: types.User, chat: Chat, _member: types.ChatMember):
def _set_cached_value(
self, user: types.User, chat: Chat, _member: types.ChatMember
):
return None # TODO

async def _get_chat_member(self, update: types.TelegramObject, user: types.User, chat: Chat, bot: Bot):
async def _get_chat_member(
self, update: types.TelegramObject, user: types.User, chat: Chat, bot: Bot
):
chat_member = self._get_cached_value(user, chat)

if chat_member is None:
Expand All @@ -59,17 +66,20 @@ async def _get_chat_member(self, update: types.TelegramObject, user: types.User,
if target_user_id is None:
return False
try:
chat_member = next(filter(lambda member: member.user.id == target_user_id, admins))
chat_member = next(
filter(lambda member: member.user.id == target_user_id, admins)
)
except StopIteration:
return False
self._set_cached_value(user, chat, chat_member)
return chat_member

async def __call__(
self, update: types.TelegramObject,
event_from_user: types.User,
chat: Chat,
bot: Bot
self,
update: types.TelegramObject,
event_from_user: types.User,
chat: Chat,
bot: Bot,
) -> bool | dict[str, Any]:
chat_member = await self._get_chat_member(update, event_from_user, chat, bot)
if not chat_member:
Expand All @@ -82,7 +92,9 @@ async def __call__(

return {self.PAYLOAD_ARGUMENT_NAME: chat_member}

def get_target_id(self, update: types.TelegramObject, user: types.User, bot: Bot) -> int | None:
def get_target_id(
self, update: types.TelegramObject, user: types.User, bot: Bot
) -> int | None:
return user.id


Expand All @@ -91,10 +103,13 @@ class TargetHasPermissions(HasPermissions):
"""
Validate the target user has specified permissions in chat
"""

can_be_same: bool = False
can_be_bot: bool = False

def get_target_id(self, message: types.Message, user: types.User, bot: Bot) -> int | None:
def get_target_id(
self, message: types.Message, user: types.User, bot: Bot
) -> int | None:
target_user = get_target_user(message, self.can_be_same, self.can_be_bot)
if target_user is None:
return None
Expand All @@ -118,5 +133,7 @@ class BotHasPermissions(HasPermissions):
}
PAYLOAD_ARGUMENT_NAME = "bot_member"

def get_target_id(self, message: types.Message, user: types.User, bot: Bot) -> int | None:
def get_target_id(
self, message: types.Message, user: types.User, bot: Bot
) -> int | None:
return bot.id
61 changes: 34 additions & 27 deletions app/handlers/base.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from aiogram import types, F, Router
from aiogram import F, Router, types
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.utils.markdown import hpre, hbold
from aiogram.utils.markdown import hbold, hpre

from app.models.db import Chat
from app.infrastructure.database.models import Chat
from app.utils.log import Logger


logger = Logger(__name__)
router = Router(name=__name__)


@router.message(Command("start", prefix='!/'))
@router.message(Command("start", prefix="!/"))
async def cmd_start(message: types.Message):
logger.info("User {user} start conversation with bot", user=message.from_user.id)
await message.answer(
Expand All @@ -22,34 +21,40 @@ async def cmd_start(message: types.Message):
)


@router.message(Command("help", prefix='!/'))
@router.message(Command("help", prefix="!/"))
async def cmd_help(message: types.Message):
logger.info("User {user} read help in {chat}", user=message.from_user.id, chat=message.chat.id)
logger.info(
"User {user} read help in {chat}",
user=message.from_user.id,
chat=message.chat.id,
)
await message.reply(
'➕Плюсануть в карму можно начав сообщение со спасибо или плюса.\n'
'➖Минусануть - с минуса.\n'
'📩Чтобы выбрать пользователя - нужно ответить реплаем на сообщение пользователя '
'или упомянуть его через @ (работает даже если у пользователя нет username).\n'
'🦾Сила, с которой пользователь меняет другим карму, зависит от собственной кармы, '
'чем она больше, тем больше будет изменение кармы у цели '
'(вычисляется как корень из кармы)\n'
'🤖Основные команды:\n'
'<code>!top</code> [chat_id] - топ юзеров по карме для текущего чата или для чата с chat_id \n'
'<code>!about</code> - информация о боте и его исходники\n'
'<code>!me</code> - посмотреть свою карму (желательно это делать в личных сообщениях с ботом)\n'
'<code>!report</code> {{реплаем}} - пожаловаться на сообщение модераторам\n'
'<code>!idchat</code> - показать Ваш id, id чата и, '
'если имеется, - id пользователя, которому Вы ответили командой'
"➕Плюсануть в карму можно начав сообщение со спасибо или плюса.\n"
"➖Минусануть - с минуса.\n"
"📩Чтобы выбрать пользователя - нужно ответить реплаем на сообщение пользователя "
"или упомянуть его через @ (работает даже если у пользователя нет username).\n"
"🦾Сила, с которой пользователь меняет другим карму, зависит от собственной кармы, "
"чем она больше, тем больше будет изменение кармы у цели "
"(вычисляется как корень из кармы)\n"
"🤖Основные команды:\n"
"<code>!top</code> [chat_id] - топ юзеров по карме для текущего чата или "
"для чата с chat_id \n"
"<code>!about</code> - информация о боте и его исходники\n"
"<code>!me</code> - посмотреть свою карму (желательно это делать в личных "
"сообщениях с ботом)\n"
"<code>!report</code> {{реплаем}} - пожаловаться на сообщение модераторам\n"
"<code>!idchat</code> - показать Ваш id, id чата и, "
"если имеется, - id пользователя, которому Вы ответили командой"
)


@router.message(Command("about", prefix='!'))
@router.message(Command("about", prefix="!"))
async def cmd_about(message: types.Message):
logger.info("User {user} about", user=message.from_user.id)
await message.reply('Исходники по ссылке https://github.com/bomzheg/KarmaBot')
await message.reply("Исходники по ссылке https://github.com/bomzheg/KarmaBot")


@router.message(Command('idchat', prefix='!'))
@router.message(Command("idchat", prefix="!"))
async def get_idchat(message: types.Message):
text = (
f"id этого чата: {hpre(message.chat.id)}\n"
Expand All @@ -63,16 +68,18 @@ async def get_idchat(message: types.Message):
await message.reply(text, disable_notification=True)


@router.message(Command('cancel'))
@router.message(Command("cancel"))
async def cancel_state(message: types.Message, state: FSMContext):
current_state = await state.get_state()
if current_state is None:
return
logger.info(f'Cancelling state {current_state}')
logger.info(f"Cancelling state {current_state}")
# Cancel state and inform user about it
await state.clear()
# And remove keyboard (just in case)
await message.reply('Диалог прекращён, данные удалены', reply_markup=types.ReplyKeyboardRemove())
await message.reply(
"Диалог прекращён, данные удалены", reply_markup=types.ReplyKeyboardRemove()
)


@router.message(F.message.content_types == types.ContentType.MIGRATE_TO_CHAT_ID)
Expand Down
Loading

0 comments on commit 9fce1d8

Please sign in to comment.