Skip to content
This repository has been archived by the owner on Jul 4, 2024. It is now read-only.

Commit

Permalink
💫 Rev Deps Inj, Structure & Basic commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Dartt0n committed Jun 28, 2022
1 parent cdea693 commit f1cce7c
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 76 deletions.
Empty file added birthy/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions birthy/bot/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from aiogram import Bot, Dispatcher
from config import config

bot = Bot(token=config.TELEGRAM_TOKEN)
dp = Dispatcher(bot=bot)
4 changes: 4 additions & 0 deletions birthy/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ def DATABASE_URL(self) -> str:
@lru_cache
def get_config():
return Config() # type: ignore # load from .env file


# export variable
config = get_config()
Empty file added birthy/database/__init__.py
Empty file.
20 changes: 20 additions & 0 deletions birthy/database/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from __future__ import annotations # better typing
from datetime import datetime
from tortoise import fields as db
from tortoise.models import Model


class Group(Model):
"""class representing a telegram group"""

telegram_id = db.IntField(pk=True)
remind_interval = db.IntField()


class Person(Model):
"""class representing a telegram user"""

telegram_id = db.IntField(pk=True)
name = db.CharField(255)
birth_date = db.DateField()
group = db.ForeignKeyField("models.Group", related_name="persons")
Empty file added birthy/handlers/__init__.py
Empty file.
85 changes: 85 additions & 0 deletions birthy/handlers/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from bot.bot import dp
from aiogram import types
from utils import scripts, validators
from database.models import Group, Person
from loguru import logger


@dp.message_handler(commands=["start"])
@validators.transaction
@validators.group_required
async def start_message(message: types.Message):
"""This handler is responsible for the behavior of the bot on /start command"""
logger.info("Start message")
telegram_id = message.chat.id
if await validators.is_registered_group(telegram_id):
await message.reply(scripts.start_registered())
else:
await message.reply(scripts.start_unregistered())


@dp.message_handler(commands=["help"])
async def help_message(message: types.Message):
"""This handler sends a help message to the user"""
await message.reply(scripts.help_message())


@dp.message_handler(commands=["group"])
@validators.transaction
@validators.group_required
async def register_group(message: types.Message):
"""This handler saves group to database if it wasn't saved"""
telegram_id = message.chat.id
if await validators.is_registered_group(telegram_id):
await message.reply(scripts.group_already_registered())
return
await Group.create(telegram_id=telegram_id, remind_interval=7)
await message.reply(scripts.group_successfully_registered())


@dp.message_handler(commands=["me"])
@validators.transaction
@validators.group_required
async def register_user(message: types.Message):
"""This handler saves user and it's birth date to database if it wasn't saved"""
pass


@dp.message_handler(commands="get_timezones")
@validators.transaction
@validators.group_required
async def get_available_timezones(message: types.Message):
"""This handler sends a list of available timezones"""
pass


@dp.message_handler(commands=["set_timezone"])
@validators.transaction
@validators.group_required
async def set_timezone_for_group(message: types.Message):
"""This handler updates groups timezone"""
pass


@dp.message_handler(commands=["nearest"])
@validators.transaction
@validators.group_required
async def get_nearest_timezones(message: types.Message):
"""This handlers sends a list of persons sorted by closest birthday to current date"""
pass


@dp.message_handler(commands=["set_remind_interval"])
@validators.transaction
@validators.group_required
async def set_remind_interval(message: types.Message):
"""This handler updates remind interval in database"""
pass


@dp.message_handler(commands=["get"])
@validators.transaction
@validators.group_required
async def get_users_birthday(message: types.Message):
"""This handler sends info about user's birthday"""
pass
20 changes: 20 additions & 0 deletions birthy/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from aiogram import executor
from bot.bot import dp
from tortoise import Tortoise, run_async # type: ignore
from config import config

# join handlers
from handlers.commands import *


async def init():
await Tortoise.init(
db_url=config.DATABASE_URL, modules={"models": ["database.models"]}
)
# Generate the schema
await Tortoise.generate_schemas()


if __name__ == "__main__":
run_async(init())
executor.start_polling(dp)
32 changes: 32 additions & 0 deletions birthy/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations
from datetime import datetime
from tortoise import fields
from tortoise.models import Model
from loguru import logger


class Group(Model):
telegram_id = fields.BigIntField(pk=True)
timezone = fields.CharField(50, default="Europe/Moscow")
do_tag = fields.BooleanField(default=False)
do_remind_in_day = fields.BooleanField(default=False)
remind_in_day = fields.IntField()

@classmethod
async def by_id(cls, telegram_id: int) -> Group | None:
return await cls.filter(telegram_id=telegram_id).get_or_none()


class Person(Model):
telegram_id = fields.BigIntField(pk=True)
name = fields.CharField(255)
date = fields.DateField()
group = fields.ForeignKeyField("models.Group", related_name="persons")

@classmethod
async def by_id(cls, telegram_id: int) -> Person | None:
return await cls.filter(telegram_id=telegram_id).get_or_none()

@property
def days_before_birthday(self):
return (self.date - datetime.now().date().replace(year=1900)).days # type: ignore
Empty file added birthy/utils/models.py
Empty file.
Empty file added birthy/utils/parser.py
Empty file.
32 changes: 32 additions & 0 deletions birthy/utils/scripts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from functools import lru_cache
import re


@lru_cache
def start_registered():
return "start_registered"


@lru_cache
def start_unregistered():
return "start_unregistered"


@lru_cache
def help_message():
return "help_message"


@lru_cache
def group_already_registered():
return "group_already_registered"


@lru_cache
def group_successfully_registered():
return "group_successfully_registered"


@lru_cache
def user_already_registered():
return "user_already_registered"
35 changes: 35 additions & 0 deletions birthy/utils/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from database.models import Group
from tortoise.transactions import in_transaction
from utils import scripts
from loguru import logger


def is_group(telegram_id: int):
return telegram_id < 0


async def is_registered_group(telegram_id: int):
return await Group.filter(telegram_id=telegram_id).exists()


def group_required(func):
logger.info("group_required")

async def wrapper(message, *args, **kwargs):
telegram_id = message.chat.id
if not is_group(telegram_id):
await message.reply(scripts.help_message())
return
await func(message)

return wrapper


def transaction(func):
logger.info("transaction")

async def wrapper(*args, **kwargs):
async with in_transaction():
return await func(*args, **kwargs)

return wrapper
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ services:
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- DATABASE_HOST=${DATABASE_HOST}
- TELEGRAM_TOKEN=${TELEGRAM_TOKEN}
depends_on:
- database
networks:
database_network:
aliases:
Expand Down
76 changes: 1 addition & 75 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ authors = ["Anton Kudryavtsev <antonkudryavtsevdoem@gmail.com>"]
python = "^3.10"
aiogram = "^2.21"
pydantic = "^1.9.1"
pendulum = "^2.1.2"
loguru = "^0.6.0"
tortoise-orm = {extras = ["asyncpg"], version = "^0.19.1"}

Expand Down

0 comments on commit f1cce7c

Please sign in to comment.