Skip to content

Commit

Permalink
Merge pull request #6
Browse files Browse the repository at this point in the history
Catch errors, make configuration easier
  • Loading branch information
usbtypec1 authored Sep 30, 2023
2 parents e956e8c + e02b974 commit d692b0c
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 13 deletions.
42 changes: 42 additions & 0 deletions commands.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[
{
"command": "contact",
"description": "📲 Добавить в контакты для отправки секретного сообщения"
},
{
"command": "work",
"description": "👩‍🚒 Работать"
},
{
"command": "balance",
"description": "💸 Мой баланс"
},
{
"command": "secret_message ",
"description": "💌 Отправить секретное сообщение"
},
{
"command": "pay",
"description": "💳 Сделать перевод средств"
},
{
"command": "yemek",
"description": "🍜 Меню на сегодня"
},
{
"command": "premium",
"description": "🌟 Премиум подписка"
},
{
"command": "hide",
"description": "🙈 Скрыть контакт"
},
{
"command": "show",
"description": "🙉 Показать контакт"
},
{
"command": "start",
"description": "⚙️ Мой профиль и настройки"
}
]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "duck-duck-bot"
version = "1.9.2"
version = "1.9.3"
description = ""
authors = ["Eldos <[email protected]>"]
readme = "README.md"
Expand Down
12 changes: 12 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import pathlib
import tomllib
from collections.abc import Mapping
Expand All @@ -10,9 +11,13 @@
'SentryConfig',
'Config',
'load_config_from_file_path',
'load_commands_from_file',
'parse_config',
)

from aiogram.types import BotCommand
from pydantic import TypeAdapter


@dataclass(frozen=True, slots=True)
class MirrorConfig:
Expand Down Expand Up @@ -96,3 +101,10 @@ def load_config_from_file_path(file_path: pathlib.Path) -> Config:
config_text = file_path.read_text(encoding='utf-8')
config = tomllib.loads(config_text)
return parse_config(config)


def load_commands_from_file(file_path: pathlib.Path) -> list[BotCommand]:
commands_text = file_path.read_text(encoding='utf-8')
commands = json.loads(commands_text)
type_adapter = TypeAdapter(list[BotCommand])
return type_adapter.validate_python(commands)
4 changes: 4 additions & 0 deletions src/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ class ThemeDoesNotExistError(Exception):

class InsufficientFundsForWithdrawalError(Exception):
pass


class InsufficientFundsForTransferError(Exception):
pass
33 changes: 22 additions & 11 deletions src/handlers/transfers.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,47 @@
from aiogram import Router, F
from aiogram.filters import StateFilter, Command, invert_f, or_f, and_f
from aiogram.types import Message
from aiogram.filters import (
StateFilter,
Command,
invert_f,
or_f,
and_f,
ExceptionTypeFilter,
)
from aiogram.types import Message, ErrorEvent

from exceptions import InsufficientFundsForTransferError
from filters import transfer_operation_filter
from repositories import BalanceRepository
from services import BalanceNotifier

router = Router(name=__name__)


@router.error(ExceptionTypeFilter(InsufficientFundsForTransferError))
async def on_insufficient_funds_for_transfer_error(event: ErrorEvent) -> None:
await event.update.message.reply(
'❌ Недостаточно средств для перевода\n'
'💸 Начните работать прямо сейчас /work'
)


@router.message(
or_f(
Command('send'),
and_f(
Command('pay'),
invert_f(transfer_operation_filter),
)
),
Command('send'),
invert_f(transfer_operation_filter),
StateFilter('*'),
)
async def on_transfer_operation_amount_invalid(
message: Message,
) -> None:
await message.reply(
'💳 Отправить перевод:\n'
'<code>/pay {сумма перевода} {описание (необязательно)}</code>'
'<code>/send {сумма перевода} {описание (необязательно)}</code>'
)


@router.message(
F.reply_to_message,
Command('pay'),
Command('send'),
invert_f(F.reply_to_message.from_user.is_bot),
transfer_operation_filter,
StateFilter('*'),
Expand Down
7 changes: 6 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from structlog.stdlib import BoundLogger

import handlers
from config import load_config_from_file_path
from config import load_config_from_file_path, load_commands_from_file
from logger import setup_logging
from middlewares import (
HTTPClientFactoryMiddleware,
Expand Down Expand Up @@ -64,6 +64,9 @@ async def main() -> None:
config_file_path = pathlib.Path(__file__).parent.parent / 'config.toml'
config = load_config_from_file_path(config_file_path)

commands_file_path = pathlib.Path(__file__).parent.parent / 'commands.json'
commands = load_commands_from_file(commands_file_path)

setup_logging(config.logging.level)

cloudinary.config(
Expand All @@ -84,6 +87,8 @@ async def main() -> None:

bot_user = await bot.me()

await bot.set_my_commands(commands)

balance_notifier = BalanceNotifier(bot)

dispatcher['bot_user'] = bot_user
Expand Down
5 changes: 5 additions & 0 deletions src/repositories/balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
ServerAPIError,
UserDoesNotExistError,
InsufficientFundsForWithdrawalError,
InsufficientFundsForTransferError,
)
from models import SystemTransaction, UserBalance, Transfer
from repositories.base import APIRepository
Expand All @@ -27,6 +28,10 @@ async def create_transfer(
'description': description,
}
async with self._http_client.post(url, json=request_data) as response:
if response.status == 400:
response_data = await response.json()
if response_data[0] == 'Insufficient funds for transfer':
raise InsufficientFundsForTransferError
if response.status != 201:
raise ServerAPIError
response_data = await response.json()
Expand Down

0 comments on commit d692b0c

Please sign in to comment.